@Shimpanze

Вопрос с собеседования: Есть ли в PHP нативная возможность инициализировать переменную как в функции preg_match()?

Здравствуйте

В функции preg_match(), можно задать третий параметр $matches в виде переменной, которая становится доступной в текущей области видимости:

preg_match( '/(foo)(bar)(baz)/', 'foobarbaz', $matches );


Можно ли в PHP такое сделать?
  • Вопрос задан
  • 203 просмотра
Решения вопроса 4
neuotq
@neuotq
Прокрастинация
Вас проверяли на знание того, как передаются переменные в функция в php. Переменные передаются всегда по значению, те передаёте переменную в функцию, туда копируется в новую переменную значение оригинальной.

С помощью амперсанда & мы можем заставить передавать ссылку на эту же переменную в памяти. И тогда манипуляции с ней внутри функции будут равны манипуляциям вне.

С объектами не большая путаница происходит, но только из-за того что многие не думают/забывают что хранится в переменной когда создаётся объект. При создании объекта в саму переменную помещается его идентификатор, по которому php и обращается к этому объекту.
Ну и соответственно при передаче такой переменной в функцию, мы копируем этот идентификатор в новую переменную. Переменная уже другая, независимая от той что была, но идентификатор объекта тот же. Поэтому манипуляции с объектом в функции(обращение к свойствам/методам) отразятся на объекте с этим идентификатором. И со стороны выглядит словно переменная с объектом всегда передаётся по ссылке(словно стоит амперсанд), но это не так. Например внутри функции вы перезапишете переменную(к примеру присвоите null) то оригинальная переменная с объектом не поменяется.

А вот есть если передать её по ссылке, те с амперсандом, то внутри функции будет переменная со ссылкой на переменную вне, и поэтому не только манипуляции с объектом, но и перетирание переменной в целом повлияет.

class A {
    public $foo = 1;
}

//создали переменную
//в ней хранится id объекта, сам объект где-то в памяти оптимизированно лежит
$newObj = new A;

//Вывод 1
echo $newObj->foo;

function foo($obj) {
	//в obj скопирован id объекта
	//тк он тот же, то меняется и оригинальный объект
	$obj->foo = 2;
	//локальная переменная перетёрся, больше id объекта не хранит
	//на внешнюю не повлияло
	$obj = null;
	
}

foo($newObj);
// получили 2
echo $newObj->foo;


function bar(&$obj) {
	//obj ссылается на тоже место в памяти, что и внешняя переменная с id объета
	//тк он тот же, то меняется и оригинальный объект (тут логично, тк по ссылке)
	$obj->foo = 2;
	//локальная переменная перетёрся, больше id объекта не хранит
	//внешняя тоже перетрётся
	$obj = null;
}


bar($newObj);
//ошибка предупреждение, нельзя читать свойства на null
echo $newObj->foo;


Ну и зная всё это, вы можете написать свою простую функцию, по типа прегматча.
function mySum($a, $b, &$result) {
	$result = $a + $b;
}
//первые два параметра по значению, в третий передаём переменную
//она тут же инициализируется (как если бы её до этого написать просто $res;)
// и передаётся её ссылка внутрь функции
mySum(1,2, $res);

//3
echo $res;
Ответ написан
Комментировать
0xD34F
@0xD34F
function f(&$x) {
  $x = 666;
}

f($xxx);

echo $xxx; // 666
Ответ написан
Комментировать
delphinpro
@delphinpro Куратор тега PHP
frontend developer
Точно так же и делается

function test(&$param)
{
    $param = 123;
}

test($parameter);

echo $parameter;
Ответ написан
Комментировать
Melkij
@Melkij
PostgreSQL DBA
function foo(&$out) 
{
	$out = 'hello!';
}

foo($hello);
var_dump($hello);
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы