質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
mysqli

MySQLiはPHP5より導入されているデータベース用のドライバです。MySQL 4.1.3以降の新しい機能の利点をまとめています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

5871閲覧

call_user_func_array()での参照渡し

toaruhetare

総合スコア141

mysqli

MySQLiはPHP5より導入されているデータベース用のドライバです。MySQL 4.1.3以降の新しい機能の利点をまとめています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

2グッド

0クリップ

投稿2016/05/14 16:11

MySQLiのオブジェクト指向型を使用してDBから値を取得してくる汎用的な関数を作ろうと考えています。

SQLステートメントのパラメータの数が可変するのでcall_user_func_arrayを使用した方法を試していますが、下記エラーが出てしまいます。

Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in XXXXXX

下記ソースが該当箇所になります。

php

1$stmt = link->prepare($sql); 2$args = create_bind_param_args($params); 3call_user_func_array(array($stmt, 'bind_param'), $args); 4$stmt->execute();

create_bind_param_argsでは渡すパラメータの配列を生成する処理を行っています。

bind_paramへのパラメータは参照渡しでなければいけないということはわかったのですが、参考にしたサイトに書かれていたようにパラメータの前に「&」を付けると

php

1call_user_func_array(array($stmt, 'bind_param'), &$args);

下記エラーが出てしまします。

Fatal error: Call-time pass-by-reference has been removed in XXXXXX

これに対する対処方法をご存知の方いませんか?

よろしくお願いします。

--
PODが使用できないレンタルサーバを使用しているため、「MySQLiではなくPDOでやったらどうか」といった助言は無用です。

KiyoshiMotoki👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

まずcreate_bind_param_argsの箇所をtakasima20さんが書かれているように

php

1$args[] = &$params[$key];

に変更
これに加えて$paramsの配列に値を追加するときに

php

1$params[] = &$foo; 2$params[] = &$hoge;

としたところ手元の環境では

php

1call_user_func_array(array($stmt, 'bind_param'), $args);

で動作しました。
phpは5.4.45です。

投稿2016/05/14 21:48

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toaruhetare

2016/05/15 09:35

コメントありがとうございます。 指摘箇所を修正したところ無事動きました。 配列に入れる前に参照渡しであることを明示しないといけないんですね。
guest

0

ここのとこの処理内容が分からないので断言はできませんが…

PHP

1$args = create_bind_param_args($params);

こちら(↓)のページは参考になると思います。
https://icondecotter.jp/blog/2013/07/19/phpmysqli%E3%81%AEsql%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AE%E6%95%B0%E3%81%8C%E5%8F%AF%E5%A4%89%E3%81%99/

ちなみに、$argsを参照渡しにするのではなく、
$args に設定する個々の情報を参照渡しにする
という話のようです。

投稿2016/05/14 17:11

takasima20

総合スコア7458

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toaruhetare

2016/05/14 17:50

コメントありがとうございます。 create_bind_param_argsの部分は下記のようになっています。 function create_bind_param_args($params) { $bind_params = ''; $args = array(); foreach ($params as $key => $value) { if(is_int($value)){ $bind_params .= 'i'; } elseif(is_double($value)){ $bind_params .= 'd'; } else { if(strpos($value, "\0") === false){ $bind_params .= 's'; } else { $bind_params .= 'b'; } } $args[] = $value; } array_unshift($args, $bind_params); return $args; } 個々の情報が参照渡しになるようにいろいろやってみましたがダメでした。
takasima20

2016/05/14 18:23

ひょっとして $args[] = &$value; ってやりました? $args[] = &$params[$key]; でどうでしょうか。 もう試してたならすんませんが…
toaruhetare

2016/05/15 09:36

コメントありがとうございます。 指摘内容はすでに試してみましたがダメでした。
guest

0

使用しているPHPのバージョンにもよる話になるみたいですが、
php5.4以降ですでに関数呼び出し時点での参照渡しはできなくなっています。

以下、Call-time pass-by-reference has been removedで単純に検索して目に付いたページを抜粋します。

参照渡しをさせたいなら、関数定義時の引数宣言部で参照渡しであることを明記する必要があります。

投稿2016/05/14 16:51

attakei

総合スコア2738

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toaruhetare

2016/05/14 17:52 編集

コメントありがとうございます。 たぶん使用しているレンタルサーバのPHPは5.4だったと思います。 関数定義時の引数宣言部で参照渡しであることを明示してみましたがダメでした。 function create_bind_param_args(&$params) { $bind_params = ''; $args = array(); foreach ($params as $key => $value) { if(is_int($value)){ $bind_params .= 'i'; } elseif(is_double($value)){ $bind_params .= 'd'; } else { if(strpos($value, "\0") === false){ $bind_params .= 's'; } else { $bind_params .= 'b'; } } $args[] = $value; } array_unshift($args, $bind_params); return $args; }
attakei

2016/05/15 03:02 編集

念のための確認なのですが、呼び出し側は call_user_func_array(array($stmt, 'bind_param'), &$args); のままなのでしょうか?
toaruhetare

2016/05/15 09:36

call_user_func_array(array($stmt, 'bind_param'), $args); にしましたがダメでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問