Объясните на пальцах, в чем разница между ссылкой на переменную и на элемент массива?

AnrDaemon

Продвинутый новичок
В #7 ты создаёшь новую переменную $d.
При этом старое значение $d нигде не инициализировано.
 

Фанат

oncle terrible
Команда форума
Не, ну с предварительной инициализацией любой дурак сможет!

Мне надо было понять, почему значение не появляется. собственно, если чуть подредактировать последний пример, то он как раз все и объясняет: https://3v4l.org/nmKdP

вопрос-то был изначально, почему
Код:
$sql = $conn -> prepare("select * from table where id = ?");
$sql -> bind_param('i', $array[0]);
$array = array(1);
$sql -> execute();
биндид null
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
все в php - переменные, константы, функции, все zval - это указатели на участки памяти, до тех пор, пока не заработал jit

$array - это структура с указателем на набор указателей на участки памяти, $array[0] - условно, структура с конкретным адресом в памяти, $a = $array[0] - копирование указателя,
а $a =& $array[0] - два действия: копирование указателя, и изменение рефкаунта

$array = array(1) - это замена указателя на новый набор данных, а старый набор никуда не девается, указатель 'i' не меняется, и содержит адрес старого zval
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
касательно проблемы, сделай каринг, там последняя строчка не уверен для php, но поймешь
PHP:
function sql(){
  return function($array){
    $sql = $conn -> prepare("select * from table where id = ?");
    $sql -> bind_param('i', $array[0]);
    return $sql -> execute();
  }
}
sql()(array(1));
 

ksnk

прохожий
пока не заработал jit
В этом случае jit не сможет освободить предыдущее место массива, так как на него есть указатель.

В этом случае тоже, imho, не то. Вероятно забиндить в шаблон нужно до реальной инициализации данных. Так что упихать возвращаемую функцию будет тупо некуда... Помог бы какой-нибудь bindParamCallback, но такого никто не удосужился придумать и добавить в PDO. Хотя, кто мешает добавить что-то новое в ядро ?
 

WMix

герр M:)ller
Партнер клуба
Так что упихать возвращаемую функцию будет тупо некуда...
я не понимаю твою проблему, return function($array) это и есть твой Callback
PHP:
function getByIdCallback($conn){
  return function($array) use ($conn){
    $sql = $conn -> prepare("select * from table where id = ?");
    $sql -> bind_param('i', $array[0]);
    return $sql;
  }
}
$sql = getByIdCallback($conn);
$result = $sql(array(1))->execute();
я малехо о $conn не подумал, вот исправленный вариант.
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Ну понятное дело что для единичного запроса все эти извращения не имеют смысла.
Это может понадобиться только для множественного выполнения.
Код:
$sql = $conn -> prepare("UPDATE table SET name=? WHERE id = ?");
$sql -> bind_param('s', $array[0], $array[1]);
foreach ($data as $array) {
    $sql -> execute();
}
А для единичного запроса (или для биндинга в цикле)оператор распаковки решает
 

ksnk

прохожий
return function($array) это и есть твой Callback
Проблема не в самих callback, а в отсутствии возможности забиндить callback-конструкцию в чистом PDO. Имеется ввиду именно чистое PDO, так как в любой надстройке над ним можно расширять функциональность без особого головняка.
Опять же, такая задача, в принципе, может возникнуть и потребовать именно таких странных телодвижений, только есть сам execute получившегося запроса делается где-то во глубинах кода, куда лазить не хочется, и в этих самых глубинах нужные нам переменные то и уже несколько раз переинициализировались... Это я про применимость такого карринига
 

WMix

герр M:)ller
Партнер клуба
PHP:
$sql = function($name, $id) use ($conn){
    $sql = $conn -> prepare("UPDATE table SET name=? WHERE id = ?");
    $sql -> bind_param('s', $name);
    $sql -> bind_param('i', $id);
    return $sql;
  };
foreach($rows as $row){
  $sql($row[0], $row[1])->execute();
}
 
Последнее редактирование:

Фанат

oncle terrible
Команда форума
Только
Код:
$sql -> bind_param('ss', $name, $id);
, за 1 вызов.
Но в общем, это уже далеко ушло от изначального вопроса :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
В этом случае jit не сможет освободить предыдущее место массива, так как на него есть указатель.
память освобождает garbage collector, с JIT он никак не связан - создай строку на 10 мегабайт, перепиши значение переменной, и наблюдай, как память не освободилась
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
на%^... зачем в PHP эти JS-костыли, которые там пишут из-за отсутствия модификаторов доступа и наследования?
это ж не тайпхинтится в PHPDoc

есть намного более веселые способы испортить жизнь коллегам
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@Фанат вот скажи, в чем суть вопроса - зачем вообще байндить по ссылке? Почему не хочешь привязывать по значению перед каждым запросом?
 

WMix

герр M:)ller
Партнер клуба
ты не писал на php4? это ж был стандартный лайфхак
я не пользовался )
зачем в PHP эти JS-костыли
в асинхронном языке, которым php хочет быть, используются callback-функции, но если ты до сих в php4 то я тебя понимаю

но дело то было не в sql()(array(1)); а в обертке function(array $array){}
 

Фанат

oncle terrible
Команда форума
@Фанат вот скажи, в чем суть вопроса - зачем вообще байндить по ссылке? Почему не хочешь привязывать по значению перед каждым запросом?
в mysqli нет привязки по значению :)
А так-то вопрос чисто теоретический.
 
Сверху