У меня есть функция запросов к базе данных, которая работает хорошо – за исключением того, что я сталкиваюсь с тем, что, по-видимому, является известной проблемой с подготовленными операциями mysqli и длинными текстовыми полями. Случается, что поле longtext всегда появляется пустым, хотя выполнение запроса через phpMyAdmin отлично работает. Согласно http://www.workinginboxershorts.com/php-mysql-returns-empty-variables-from-longtext-column , переключение типа данных в текст решает проблему. Однако в моем случае я бы предпочел оставить поле длинным текстом, поскольку я могу предвидеть, когда это дополнительное пространство будет ценным.
Я использую параметризованные запросы, что, очевидно, является проблемой. Вот моя функция:
// Bind results to an array // $stmt = sql query, $out = array to be returned function stmt_bind_assoc (&$stmt, &$out) { $data = mysqli_stmt_result_metadata($stmt); $fields = array(); $out = array(); $fields[0] = $stmt; $count = 1; while($field = mysqli_fetch_field($data)) { $fields[$count] = &$out[$field->name]; $count++; } call_user_func_array('mysqli_stmt_bind_result', $fields); } // DB Query // $query = SQL query, $params = array of parameters, $rs = whether or not a resultset is expected, $newid = whether or not to retrieve the new ID value; // $onedimensionkey = key required to convert array into simple one dimensional array function db_query($query, $params, $rs = true, $newid = false, $onedimensionkey = false) { $link = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME); if (!$link) { print 'Error connecting to MySQL Server. Errorcode: ' . mysqli_connect_error(); exit; } // Prepare the query and split the parameters array into bound values if ($sql_stmt = mysqli_prepare($link, $query)) { if ($params) { $types = ''; $new_params = array(); $params_ref = array(); // Split the params array into types string and parameters sub-array foreach ($params as $param) { $types .= $param['type']; $new_params[] = $param['value']; } // Cycle the new parameters array to make it an array by reference foreach ($new_params as $key => $parameter) { $params_ref[] = &$new_params[$key]; } call_user_func_array('mysqli_stmt_bind_param', array_merge(array($sql_stmt, $types), $params_ref)); } } else { print 'Error: ' . mysqli_error($link); exit(); } // Execute the query mysqli_stmt_execute($sql_stmt); // If there are results to retrive, do so if ($rs) { $results = array(); $rows = array(); $row = array(); stmt_bind_assoc($sql_stmt, $results); while (mysqli_stmt_fetch($sql_stmt)) { foreach ($results as $key => $value) { $row[$key] = $value; } $rows[] = $row; } if ($onedimensionkey) { $i = 0; foreach ($rows as $row) { $simplearray[$i] = $row[$onedimensionkey]; $i++; } return $simplearray; } else { return $rows; } } // If there are no results but we need the new ID, return it elseif ($newid) { return mysqli_insert_id($link); } // Close objects mysqli_stmt_close($sql_stmt); mysqli_close($link); }
Согласно ссылке, которую я опубликовал, есть временное решение, связанное с порядком, в котором все сделано, но либо я обрабатываю свой запрос совершенно другим способом, чем примером, либо просто не понимаю что-то важное.
Спасибо всем, кто может помочь!
EDIT: Благодаря ответу Корины я решил это – для всех, кто сталкивается с проблемой, вам просто нужно добавить следующее после команды mysql_stmt_execute:
// Execute the query mysqli_stmt_execute($sql_stmt); // Store results mysqli_stmt_store_result($sql_stmt);
Мне удалось решить ту же проблему, вызвав mysqli_stmt_store_result перед привязкой данных.
У кого-то была такая же проблема и поделился ответом на веб-сайте php.net :
По-видимому, если у вас есть longtext present, вам нужно вызвать store_result, прежде чем использовать bind_result.