Php сформировать имя переменной

Php сформировать имя переменной

БлогNot. PHP: используем статическую переменную класса и динамически формируем имя переме.

PHP: используем статическую переменную класса и динамически формируем имя переменной класса

С целью решения поставленных в заголовке задач напишем небольшой класс на PHP с именем democlass .

В этом классе опишем приватную переменную $var , а также статический (общий для всех экземпляров класса) элемент $count . С его помощью мы будем считать количество созданных экземпляров класса — значение $count будет увеличиваться на 1 в конструкторе __construct и уменьшается на 1 в деструкторе __destruct . Также конструктор может инициализировать переменную $ var , если ему передан ненулевой аргумент. Листинг демо-класса:

var = $var; democlass::$count++; > function __destruct() < democlass::$count--; >function view () < $numargs = func_num_args(); $arglist = func_get_args(); echo '
'; for ($i = 0; $i < $numargs; $i++) < $var = $arglist[$i]; echo '$'.$var.'='.$this->var.' '; > > > ?>

Про функцию view нужно сказать несколько слов отдельно — она умеет принимать переменное число аргументов, которые должны быть именами переменных класса без предшествующего » $ » (у нас в классе всего одна нестатическая переменная, поэтому при тестовом вызове функции мы можем, например, напечатать значение $var дважды) и печатать с новой строки нужные переменные класса в виде имя=значение . Это может пригодиться при анализе и отладке классов на PHP.

Теперь напишем скрипт, использующий наш демо-класс и показывающий создание, удаление и просмотр объектов:

__destruct(); echo '
1 object deleted, $count='.democlass::$count; $c1->view ('var'); $c2->view ('var','var'); ?>

Вообще-то PHP не нуждается в явных вызовах деструкторов, а объекты «живут» до конца выполнения скрипта, поэтому после явного вызова деструктора для объекта $c2

Читайте также:  Php get object vars foreach

значение $count уменьшится, но объект прекрасно будет существовать, что видно из последующего вызова $c2->view .

Вот результаты выполнения скрипта:

2 objects created, $count=2 1 object deleted, $count=1 $var=0 $var=1 $var=1

19.03.2013, 13:03 [8979 просмотров]

Источник

Как получить имя переменной в виде строки в PHP?

Скажем, у меня есть этот PHP-код:

$FooBar = «a string»;

Затем мне нужна такая функция:

print_var_name($FooBar);

которая печатает:

FooBar

Любые идеи, как этого добиться? Возможно ли это вообще в PHP?

Ответ 1

Вы можете использовать get_defined_vars(), чтобы определить имя переменной, которая имеет то же значение, что и та, имя которой вы пытаетесь найти. Очевидно, это не всегда будет работать, поскольку разные переменные часто имеют одинаковые значения, но это единственный способ, который я могу придумать для этого.

get_defined_vars() в некоторых ситуациях работает некорректно, она возвращает var, потому что $var используется в самой функции.

function print_var_name($var)

foreach($GLOBALS as $var_name => $value)

if ($value === $var)

return $var_name;

>

>

return false;

>

В PHP нет хорошего способа сделать это, вероятно, потому, что вам не нужно этого делать. Возможно, есть более эффективные способы сделать то, что вы пытаетесь сделать.

Ответ 2

Я не могу уверенно утверждать, как сделать это эффективно, но я придумал вот что. Это работает для ограниченного использования, как указа н о ниже.

function varName( $v )

$trace = debug_backtrace();

$vLine = file( __FILE__ );

$fLine = $vLine[ $trace[0][‘line’] — 1 ];

preg_match( «#\\$(\w+)#», $fLine, $match );

print_r( $match );

>

$foo = «knight»;

$bar = array( 1, 2, 3 );

$baz = 12345;

varName( $foo );

varName( $bar );

varName( $baz );

?>

// Результат

Array (

[0] => $foo [1] => foo

)

Array (

[0] => $bar [1] => bar

)

Array (

[0] => $baz [1] => baz

)

Это работает на основе строки, вызывающей функцию, где она находит аргумент, который вы передали. Я полагаю, что его можно было бы расширить для работы с несколькими аргументами, но, если бы вы могли лучше объяснить ситуацию, вероятно, другое решение будет работать лучше.

Ответ 3

  • «Переменная» — это просто символ, указывающий на что-то еще. В PHP она внутренне указывает на что-то, называемое «zval», которое на самом деле может использоваться для нескольких переменных одновременно либо потому, что они имеют одинаковое значение (PHP реализует то, что называется «копирование при записи», поэтому для $foo = $bar нет необходимости выделить дополнительную память сразу) , либо потому, что они были назначены (или переданы функции) по ссылке (например , $foo =& $bar ).
  • Когда вы передаете параметр функции, вы создаете новую переменную (даже если это ссылка). Вы можете передать что-то анонимное, например , «hello» , но, оказавшись внутри вашей функции, это будет та переменная, как вы ее назовете. Это довольно фундаментально для разделения кода: если бы функция полагалась на то, как называлась переменная, она была бы больше похожа на goto, чем отдельную функцию.
  • Глобальные переменные обычно считаются плохой идеей. Многие примеры здесь предполагают, что переменная, которую вы хотите «отразить», может быть найдена в $GLOBALS , но это будет верно только в том случае, если вы плохо структурировали свой код и переменные не привязаны к какой-либо функции или объекту.
  • Имена переменных помогают программистам читать свой код. Переименование переменных в соответствии с их назначением — очень распространенная практика рефакторинга, и все дело в том, что это не имеет никакого значения.

Ответ 4

Это именно то, что вам нужно , — готовая к использованию функция «скопируй и вставь», которая определяет имя заданной переменной:

function print_var_name()

// читаем обратную трассировку

$bt = debug_backtrace();

// читаем файл

$file = file($bt[0][‘file’]);

// выбираем точную строку print_var_name($varname)

$src = $file[$bt[0][‘line’]-1];

// шаблон поиска

$pat = ‘#(.*)’.__FUNCTION__.’ *?\( *?(.*) *?\)(.*)#i’;

// извлечение $varname из совпадения №2

$var = preg_replace($pat, ‘$2’, $src);

// выводим в браузер

echo ‘

' . trim($var) . ' = ' . print_r(current(func_get_args()), true) . '

‘;

>

Мы будем очень благодарны

если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

Источник

Как получить имя переменной в виде строки в PHP?

Вы можете использовать get_defined_vars(), чтобы найти имя переменной, которая имеет то же значение, что и то, которое вы пытаетесь найти Имя. Очевидно, что это не всегда будет работать, поскольку разные переменные часто имеют одинаковые значения, но это единственный способ, которым я могу это сделать. Изменить: get_defined_vars() работает некорректно, он возвращает ‘var’, потому что $$ используется в самой функции. $GLOBALS, похоже, работает, поэтому я изменил его на это.

function print_var_name($var) < foreach($GLOBALS as $var_name =>$value) < if ($value === $var) < return $var_name; >> return false; > 

Изменить: чтобы быть ясным, в PHP нет хорошего способа сделать это, вероятно, потому, что вам не нужно это делать. Вероятно, есть лучшие способы сделать то, что вы пытаетесь сделать.

Я тоже не мог придумать способ сделать это эффективно, но я придумал это. Он работает для ограниченного использования ниже. развести руками

 $foo = "knight"; $bar = array( 1, 2, 3 ); $baz = 12345; varName( $foo ); varName( $bar ); varName( $baz ); ?> // Returns Array ( [0] => $foo [1] => foo ) Array ( [0] => $bar [1] => bar ) Array ( [0] => $baz [1] => baz ) 

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

$var_name = "FooBar"; $$var_name = "a string"; 
  • «Переменная» — это просто символ, указывающий на что-то другое. В PHP он внутренне указывает на то, что называется «zval», которое фактически может использоваться для нескольких переменных одновременно, либо потому, что они имеют одинаковое значение (PHP реализует нечто, называемое «copy-on-write», так что $foo = $bar doesn ‘ t необходимо выделить дополнительную память сразу) или потому, что они были назначены (или переданы функции) по ссылке (например, $foo =& $bar ). Таким образом, zval не имеет имени.
  • Когда вы передаете параметр функции, вы создаете новую переменную (даже если это ссылка). Вы можете передать что-то анонимное, например «hello» , но один раз внутри вашей функции, какую бы переменную вы ни назвали. Это довольно фундаментально для разделения кода: если функция полагалась на то, что была вызвана переменной, это было бы скорее как goto , чем правильно отдельная функция.
  • Глобальные переменные обычно считаются плохими. Многие примеры здесь предполагают, что переменную, которую вы хотите «отразить», можно найти в $GLOBALS , но это будет верно, только если вы плохо структурировали свой код, а переменные не привязаны к какой-либо функции или объекту.
  • Переменные имена есть, чтобы помочь программистам прочитать их код. Переименование переменных, чтобы лучше соответствовать их назначению, является очень распространенной практикой рефакторинга, и все дело в том, что это не имеет никакого значения.

Теперь я понимаю стремление к этому для отладки (хотя некоторые из предложенных применений выходят далеко за рамки этого), но в качестве обобщенного решения это на самом деле не так полезно, как вы могли подумать: если ваша функция отладки говорит, что ваша переменная называется «$ file» , который все равно может быть любой из десятков переменных «$ file» в вашем коде или переменной, которую вы назвали «$ filename», но передаете функцию, параметр которой называется «$ file» .

Более полезная часть информации — это то, где в коде вызывается функция отладки. Поскольку вы можете быстро найти это в своем редакторе, вы можете увидеть, какую переменную вы выводили для себя, и можете даже передать в нее целые выражения за один раз (например, debug(‘$foo + $bar = ‘ . ($foo + $bar)) ).

Для этого вы можете использовать этот фрагмент в верхней части своей функции отладки:

$backtrace = debug_backtrace(); echo '# Debug function called from ' . $backtrace[0]['file'] . ' at line ' . $backtrace[0]['line']; 

Я сделал функцию проверки для отладки. Это похоже на print_r() на стероиды, подобно Krumo, но немного эффективнее на объектах. Я хотел добавить определение имени var и вышел с этим, вдохновленный сообщением Ника Престы на этой странице. Он обнаруживает любое выражение, переданное как аргумент, а не только имена переменных.

Это только функция-обертка, которая обнаруживает переданное выражение. Работает в большинстве случаев. Он не будет работать, если вы вызовете функцию более одного раза в одной строке кода.

Это прекрасно работает: умереть (инспектировать ( $this- > GetUser() → hasCredential ( «Удалить» ) ));

inspect() — это функция, которая будет обнаруживать переданное выражение.

Мы получаем: $this- > getUser() → hasCredential ( «delete» )

function inspect($label, $value = "__undefin_e_d__") < if($value == "__undefin_e_d__") < /* The first argument is not the label but the variable to inspect itself, so we need a label. Let try to find out it name by peeking at the source code. */ /* The reason for using an exotic string like "__undefin_e_d__" instead of NULL here is that inspected variables can also be NULL and I want to inspect them anyway. */ $value = $label; $bt = debug_backtrace(); $src = file($bt[0]["file"]); $line = $src[ $bt[0]['line'] - 1 ]; // let match the function call and the last closing bracket preg_match( "#inspect\((.+)\)#", $line, $match ); /* let count brackets to see how many of them actually belongs to the var name Eg: die(inspect($this->getUser()->hasCredential("delete"))); We want: $this->getUser()->hasCredential("delete") */ $max = strlen($match[1]); $varname = ""; $c = 0; for($i = 0; $i < $max; $i++)< if( $match[1]== "(" ) $c++; elseif( $match[1] == ")" ) $c--; if($c < 0) break; $varname .= $match[1]; > $label = $varname; > // $label now holds the name of the passed variable ($ included) // Eg: inspect($hello) // => $label = "$hello" // or the whole expression evaluated // Eg: inspect($this->getUser()->hasCredential("delete")) // => $label = "$this->getUser()->hasCredential(\"delete\")" // now the actual function call to the inspector method, // passing the var name as the label: // return dInspect::dump($label, $val); // UPDATE: I commented this line because people got confused about // the dInspect class, wich has nothing to do with the issue here. echo("The label is: ".$label); echo("The value is: ".$value); > 

Здесь приведен пример функции инспектора (и моего класса dInspect):

Тексты находятся на испанском языке на этой странице, но код является кратким и очень легким для понимания.

Источник

Оцените статью