PHP mysqli wrapper: передача по ссылке с помощью __call () и call_user_func_array ()

Я – долгожданный поклонник stackoverflow, первый плакат. Мне очень хотелось бы посмотреть, сможет ли кто-нибудь помочь мне в этом. Позвольте мне копаться с небольшим кодом, тогда я объясню свою проблему. У меня есть следующие классы-оболочки:

class mysqli_wrapper { private static $mysqli_obj; function __construct() // Recycles the mysqli object { if (!isset(self::$mysqli_obj)) { self::$mysqli_obj = new mysqli(MYSQL_SERVER, MYSQL_USER, MYSQL_PASS, MYSQL_DBNAME); } } function __call($method, $args) { return call_user_func_array(array(self::$mysqli_obj, $method), $args); } function __get($para) { return self::$mysqli_obj->$para; } function prepare($query) // Overloaded, returns statement wrapper { return new mysqli_stmt_wrapper(self::$mysqli_obj, $query); } } class mysqli_stmt_wrapper { private $stmt_obj; function __construct($link, $query) { $this->stmt_obj = mysqli_prepare($link, $query); } function __call($method, $args) { return call_user_func_array(array($this->stmt_obj, $method), $args); } function __get($para) { return $this->stmt_obj->$para; } // Other methods will be added here } 

Моя проблема в том, что когда я вызываю bind_result() в классе mysqli_stmt_wrapper , мои переменные, похоже, не передаются по ссылке и ничего не возвращаются. Чтобы проиллюстрировать, если я запустил этот раздел кода, я получаю только NULL:

 $mysqli = new mysqli_wrapper; $stmt = $mysqli->prepare("SELECT cfg_key, cfg_value FROM config"); $stmt->execute(); $stmt->bind_result($cfg_key, $cfg_value); while ($stmt->fetch()) { var_dump($cfg_key); var_dump($cfg_value); } $stmt->close(); 

Я также получаю хорошую ошибку от PHP, которая говорит мне: PHP Warning: Parameter 1 to mysqli_stmt::bind_result() expected to be a reference, value given in test.php on line 48


Я попытался перегрузить bind_param() , но я не могу понять, как получить переменное количество аргументов по ссылке. func_get_args() , похоже, не в состоянии помочь.

Если я $stmt->bind_result(&$cfg_key, &$cfg_value) переменные по ссылке, как в $stmt->bind_result(&$cfg_key, &$cfg_value) она должна работать, но это устаревшее поведение и вызывает больше ошибок.

У кого-нибудь есть идеи вокруг этого? Большое спасибо за ваше время.

Solutions Collecting From Web of "PHP mysqli wrapper: передача по ссылке с помощью __call () и call_user_func_array ()"

Если вы выйдете из класса mysqli_stmt, вы обойдете проблему с ссылкой. (который не имеет чистого раствора)

 class mysqli_stmt_wrapper extends mysqli_stmt { public function __construct($link, $query) { parent::__construct($link, $query); } } class mysqli_wrapper extends mysqli { public function prepare($query) { return new mysqli_stmt_wrapper($this, $query); } } 

Немного помогая ребятам из канала #php irc, я придумал следующее решение:

 // We have to explicitly declare all parameters as references, otherwise it does not seem possible to pass them on without // losing the reference property. public function bind_result (&$v1 = null, &$v2 = null, &$v3 = null, &$v4 = null, &$v5 = null, &$v6 = null, &$v7 = null, &$v8 = null, &$v9 = null, &$v10 = null, &$v11 = null, &$v12 = null, &$v13 = null, &$v14 = null, &$v15 = null, &$v16 = null, &$v17 = null, &$v18 = null, &$v19 = null, &$v20 = null, &$v21 = null, &$v22 = null, &$v23 = null, &$v24 = null, &$v25 = null, &$v26 = null, &$v27 = null, &$v28 = null, &$v29 = null, &$v30 = null, &$v31 = null, &$v32 = null, &$v33 = null, &$v34 = null, &$v35 = null) { // debug_backtrace returns arguments by reference, see comments at http://php.net/manual/de/function.func-get-args.php $trace = debug_backtrace(); $args = &$trace[0]['args']; return call_user_func_array(array($this->mysqlObj, 'bind_result'), $args); } 

Я предполагаю, что это потому, что оригинальная сигнатура функции указывает, что она ожидает ссылки, тогда как ваш __call не может этого сделать. Поэтому попробуйте не использовать __call но явно добавив bind_result с той же сигнатурой функции, что и оригинал.