Ответ 1
PHP 5.4 теперь поддерживает разблокирование массива функций, что означает, что вы можете сделать это:
if ($r && $r->num_rows)
{
$row = $r->fetch_assoc()['blah'];
}
Я переношу некоторый старый PHP-код из mysql в MySQLi, и я столкнулся с небольшим недостатком.
Нет ли эквивалента старой mysql_result()
функции?
Я знаю, что mysql_result()
работает медленнее, чем другие функции, когда вы работаете с более чем 1 строкой, но много времени у меня есть только 1 результат и 1 поле. Используя его, я могу сконденсировать 4 строки в 1.
Старый код:
if ($r && mysql_num_rows($r))
$blarg = mysql_result($r, 0, 'blah');
Требуемый код:
if ($r && $r->num_rows)
$blarg = $r->result(0, 'blah');
Но такой вещи нет.: (
Есть ли что-то, что мне не хватает? Или мне придется сосать его и сделать все:
if ($r && $r->num_rows)
{
$row = $r->fetch_assoc();
$blarg = $row['blah'];
}
PHP 5.4 теперь поддерживает разблокирование массива функций, что означает, что вы можете сделать это:
if ($r && $r->num_rows)
{
$row = $r->fetch_assoc()['blah'];
}
Во время ответа я подумал, что смогу улучшить ответ, заданный после того же вопроса. Следующая функция полностью реплицирует функцию mysql_result() и возвращает false, когда вы находитесь вне границ вашего запроса (пустой результат, ни одна строка этого номера, ни один столбец этого номера). У него есть дополнительное преимущество, которое, если вы не укажете строку, принимает 0,0 (одно меньшее значение, которое нужно передать). Функция была обновлена с учетом численного смещения поля или имени поля.
function mysqli_result($res,$row=0,$col=0){
$numrows = mysqli_num_rows($res);
if ($numrows && $row <= ($numrows-1) && $row >=0){
mysqli_data_seek($res,$row);
$resrow = (is_numeric($col)) ? mysqli_fetch_row($res) : mysqli_fetch_assoc($res);
if (isset($resrow[$col])){
return $resrow[$col];
}
}
return false;
}
function db_result($result,$row,$field) {
if($result->num_rows==0) return 'unknown';
$result->data_seek($row);
$ceva=$result->fetch_assoc();
$rasp=$ceva[$field];
return $rasp;
}
Вы можете сделать это, извлекая объект вместо массива.
$mysqli->query("SELECT email FROM users WHERE userid = 'foo'")->fetch_object()->email;
Вам нужно PHP 5+ использовать цепочку методов таким образом.
В качестве альтернативы, если вы используете процедурный MySQLi, легко написать свою собственную функцию mysqli_result
, которая соответствует mysql_result
.
Ну, вы всегда можете укоротить его примерно так:
if ($r && $r->num_rows)
list($blarg) = $r->fetch_row();
Но это может быть так хорошо, как вы собираетесь получить.
Я предлагаю вам добавить эту строку в решение Cris, чтобы получить результат, выполнив db_result('mytable.myfield)
и db_result('myfield')
, так как это поведение по умолчанию исходной функции mysql_result
.
function db_result($result,$row,$field) {
if($result->num_rows==0) return 'unknown';
$result->data_seek($row);
$ceva=$result->fetch_assoc();
return (isset($ceva[$field])?$ceva[$field]
:(strpos($field,'.')?$ceva[substr($field,strrpos($field,'.')+1)]:''));
}
Если вы выберете только одно поле в запросе и вы ожидаете только одного возвращенного данных выбранного поля, то это работает:
function mysqli_datum($result)
{
if ($result->num_rows == 0)
return;
$result->data_seek(0);
$row=$result->fetch_row();
return $row[0];
}
Здесь приведена адаптация ответа Марио Лурига с использованием объекта mysqli_result
вместо процедурной версии mysqli
.
/**
* Accepts int column index or column name.
*
* @param mysqli_result $result
* @param int $row
* @param int|string $col
* @return bool
*/
function resultMysqli(mysqli_result $result,$row=0,$col=0) {
//PHP7 $row can use "int" type hint in signature
$row = (int)$row; // PHP5 - cast to int
if(!is_numeric($col) ) { // cast to string or int
$col = (string)$col;
} else {
$col = (int)$col;
}
$numrows = $result->num_rows;
if ($numrows && $row <= ($numrows-1) && $row >=0) {
$result->data_seek($row);
$resrow = (is_numeric($col)) ? $result->fetch_row() : $result->fetch_assoc();
if (isset($resrow[$col])){
return $resrow[$col];
}
}
return false;
}
В итоге я использовал пользовательскую функцию, используя процедурный стиль:
function mysqli_result($res, $row, $field=0) {
mysqli_data_seek($res, $row);
return mysqli_fetch_array($res)[$field];
}
Ссылка: https://www.sitepoint.com/community/t/change-mysql-result-to-mysqli/190972/6
Это хороший ответ: http://php.net/manual/es/class.mysqli-result.php
<?php
function mysqli_result($result,$row,$field=0) {
if ($result===false) return false;
if ($row>=mysqli_num_rows($result)) return false;
if (is_string($field) && !(strpos($field,".")===false)) {
$t_field=explode(".",$field);
$field=-1;
$t_fields=mysqli_fetch_fields($result);
for ($id=0;$id<mysqli_num_fields($result);$id++) {
if ($t_fields[$id]->table==$t_field[0] && $t_fields[$id]->name==$t_field[1]) {
$field=$id;
break;
}
}
if ($field==-1) return false;
}
mysqli_data_seek($result,$row);
$line=mysqli_fetch_array($result);
return isset($line[$field])?$line[$field]:false;
}
?>
Я использую следующую функцию для замены mysql_result()
function mysqli_result($result, $iRow, $field = 0)
{
if(!mysqli_data_seek($result, $iRow))
return false;
if(!($row = mysqli_fetch_array($result)))
return false;
if(!array_key_exists($field, $row))
return false;
return $row[$field];
}
Если вы ищете надежную библиотеку для подключения к базе данных, я предлагаю вам использовать AdoDB. Эта библиотека может подключаться к нескольким базам данных, и вам не нужно переписывать свой запрос, если вы меняете базу данных, если она не содержит какого-либо конкретного SQL-кода для определенного механизма базы данных. Проверьте эту страницу для примера использования. Кроме того, если вы используете PHP5, вы можете использовать foreach для итерации.
Я надеюсь, что это поможет вам преобразовать любые старые коды в более надежный и кросс-код базы данных.