web-dev-qa-db-ja.com

配列として準備された選択ステートメントの結果

後でstr_replace()関数で使用するために、準備されたステートメントの完全な結果を配列(キー/値のペア)として取得したいと思います。

私のテーブルには3つの列、インデックスとフィールド「x1」と「x2」があります。私は以下をうまく使いました:

_$db = new mysqli("servername", "username", "pw", "dbname");

if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table")) {
  $ps1->execute();
  $ps1->bind_result($search, $replace);
    $result = array();
    while ($ps1->fetch()) {
      $result[$search] = $replace;
    }
    $ps1->close();
}
_

ただし、whileループなしで、単一の行から1つずつ加算されない完全な結果を取得する、より簡単な方法が必要だと考えています。

他の質問を見て、次のことを思いつきましたが、うまくいきません( "警告:mysqli_fetch_assoc()はパラメーター1がmysqli_resultであることを期待しています"):

_if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table")) {
  $ps1->execute();
  $result = mysqli_fetch_assoc($ps1);
  return $result;
  $ps1->close();
}
_

私も$result = mysqli_fetch_all($ps1);を試しましたが、成功しませんでした(「未定義の関数mysqli_fetch_all()の呼び出し」を取得しました)。

ところで、私はPHP 5.6。


MYSQLNDに関するコメントでのいくつかの回答と議論の後の追加:

phpinfo()は、mysqlndセクションに次の情報を表示します。

ロードされたプラグイン:mysqlnd、debug_trace、auth_plugin_mysql_native_password、auth_plugin_mysql_clear_password、auth_plugin_sha256_password

14
Johannes

このようなことを試しましたか?

$db = new mysqli("servername", "username", "pw", "dbname");

if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table")) {
  $ps1->execute();
  $result = $ps1->fetchAll(PDO::FETCH_NAMED);
  $ps1->close();
}

更新

私はこれを意味しています(あなたがインストールした場合mysqlndドライバ)

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 150,5";

if ($stmt = mysqli_prepare($link, $query)) {

    /* execute statement */
    mysqli_stmt_execute($stmt);

    /* get result object */
    $result = mysqli_fetch_all(mysqli_stmt_get_result($stmt));

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>
0
IVO GELOV

確かにもっと簡単な方法があります。 array_column の使用を検討してください:

$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT x1, x2 FROM my_table";

if ($stmt = mysqli_prepare($link, $query)) {

    /* execute statement */
    mysqli_stmt_execute($stmt);

    /* get result object */
    $rows = mysqli_fetch_all(mysqli_stmt_get_result($stmt), MYSQLI_ASSOC);

    /* get formatted object */
    $result = array_column($rows, 'x2', 'x1');

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);

編集:手続き型mysqli関数を使用するように回答を更新

2
JesusTheHun

すみません、英語

_mysqli_result_が_mysqli->prepare->execute_オブジェクトを返すのに対し、mysqli_fetch_assoc()は_mysqli_stmt_を引数として取るので、それは可能ではないと思います。

あなたができることは、手続き的な方法で JesusTheHun's を使用するか、_prepare and execute_の代わりに$ps1 = $db->query($stmt)を使用して$ps1->fetch_all(MYSQLI_ASSOC)に渡すことです。

例:

_if($ps1 = $db->query("SELECT x1, x2 FROM my_table")) {
  $result = $ps1->fetch_all(MYSQLI_ASSOC);

  $ps1->close();
  return $result;
}

print_r($result);
_

mysqli のPHPドキュメント

1
Saleh Mahmood

これは私が fetch_all mysqliを使用した準備済みステートメントの結果

$stmt = $db->prepare("SELECT x1, x2 FROM my_table")
$stmt->execute();
$result = $stmt->get_result();
$allRows = $result->fetch_all(MYSQLI_ASSOC);
1
Accountant م

以前の回答から(適切なmysqlnd拡張子がない-2つあり、1つはmysqli用、もう1つはPDO用)、2つあると結論付けることができます。オプションでは、準備されたステートメントをwhileループまたは標準クエリで使用できますが、結果は連想配列として返されます。

パラメータがないため、プレーンoleクエリを安全に使用できます。

a)エスケープする必要のあるユーザー入力はなく、ステートメントにはパラメーターがないため、セキュリティ上のリスクはありません。

b)準備されたステートメントのパフォーマンスの向上は、プレーンOLE SQLクエリとして使用しているため、無視できます。同じステートメントを何度も再利用して、バインドしたパラメーター値のみを変更すると、準備済みステートメントが輝きます。

さあ、追いかけましょう:

$conn = mysqli($Host, $user, $pass, $dbname);

$query = $conn->query("SELECT x1, x2 FROM your_table");

$result = $query->fetch_assoc();

結果は次の形式になります。

[
   'x1' => 'v1',
   'x2' => 'v2'
]

1つのアイテムだけでなく、データセット全体が必要な場合は、以下を使用します。

$result = $query->fetch_all(MYSQLI_ASSOC);

結果は次のようになります。

[
    [
      'x1' => 'v1',
      'x2' => 'v2'
   ],
   [
     'x1' => 'v1',
     'x2' => 'v2'
   ],
   ...
]

[〜#〜]更新[〜#〜]

mysqli::fetch_allもエラーをスローすることがわかりました。ループなしではデータセット全体をフェッチする方法はありません。あなたがあなたのアプローチの代替案を望むなら、おそらくこのようなものです:

$query = $conn->query("SELECT x1, x2 FROM your_table");

$results = [];
for ($i = 0; $i < $query->num_rows; $i++) {
    $row = $query->fetch_assoc();
    $results[$row['x1']] = $row['x2'];
}

またはこれ:

while($row = $query->fetch_assoc()) {
   $results[$row['x1']] = $row['x2'];  
}

ただし、正直に言うと、最初の方法を使用することもできます。mysqli::fetch_allがない場合は、これが最善の方法です。

0
Sasa Blagojevic

Mysqli_resultクラスを次のような関数で拡張してみてください。

public function my_fetch_keyval() {
    for ($result = array(); $tmp = $this->fetch_row();) {
        // Expecting 2 columns. 1st = Key; 2nd = Value
        $result[$tmp[0]] = $tmp[1];
    }
    return $result;
}

次に、コードでそれを使用できます。

if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table")) {
    $ps1->execute();
    $my_assoc_array = $ps1->my_fetch_keyval();
    $ps1->close();
}
0
Julio

編集:私はあなたのコメントやその他の回答を確認しましたが、Mysqlネイティブドライバーがないことは明らかです。

Mysqlndを使用したくない場合は、whileループを解消できないと思います;)

================================================== ==========

ひとつ欠けているようです!

get_result()メソッドを呼び出してから、そのオブジェクトでfetch_all()を呼び出す必要があります。

$db = new mysqli("servername", "username", "pw", "dbname");

if($ps1 = $db->prepare("SELECT x1, x2 FROM my_table")) {
    $ps1->execute();
    $result = $ps1->get_result()->fetch_all();
    //return $result;
    $ps1->close();
}

echo '<pre>';
print_r($result);

また、その時点でスクリプトの実行を終了するため、returnステートメントをコメントアウトしていることにも注意してください。

それが役に立てば幸い :)

0
Nimeshka Srimal