Возможно ли расширить функцию вызова функции в строке PHP?
Я попытался вызвать foo() внутри строки следующим образом:
echo "This is a $ car"; function foo()
но в результате получается синтаксическая ошибка.
Я нашел здесь нечто похожее, но не совсем то, что мне нужно:
echo "This is the value of the var named by the return value of getName(): >";
Является ли это возможным? Нет.
Функции, вызовы методов, статические переменные класса и константы класса внутри работают с PHP 5. Однако доступное значение будет интерпретироваться как имя переменной в области, в которой определена строка. Использование отдельных фигурных скобок (<>) не будет работать для доступа к возвращаемым значениям функций или методов или значений констант класса или переменных статического класса.
Нет, насколько я знаю, вы можете делать только:
echo "hello ".foo(); function foo()
В вашем примере это будет работать:
$name = "captaintokyo"; echo "This is the value of the var named by the return value of getName(): >"; function getName() < return "name"; >// Output: // This is the value of the var named by the return value of getName(): captaintokyo
$func = function($param) < return $param; >; function foo($color) < return "$color car"; >echo "This is a
"; $title = 'blue car'; echo "This is a <$func(str_replace('blue', 'red', $title))>
";
$ func () будет вызываться как функция, а выражение в круглых скобках будет оцениваться как любой другой PHP-код. Таким образом, вы можете напрямую вызывать почти любую функцию внутри строки.
Вы также можете это сделать:
Оберните $ в одинарные кавычки, чтобы он не был для меня буквальным, и используйте конкатенацию, чтобы добавить значение foo
Этот пример не будет работать, потому что использование функций в формате PHP позволяет вам получить доступ к результату как имя переменной, а затем отобразить содержимое этой переменной.
В вашем примере оператор echo будет пытаться отобразить содержимое переменной с именем $hello .
Чтобы понять, почему он не работает, нам нужно изменить пример:
function foo() $hello="world"; echo "$";
Эта программа будет печатать world . Похоже, это то, что вы нашли во втором примере, который вы дали.
Если вы надеетесь получить программу, которая будет печатать hello в вашем примере, вы не сможете сделать это, используя эту технику. Однако хорошая новость заключается в том, что есть много гораздо более простых способов сделать это. Просто выделите возвращаемое значение функции.
Синтаксис $ <> выглядит как замена командной оболочки, для PHP вы можете использовать eval, http://php.net/eval
Но будьте предупреждены, что eval – это зло … Вы должны быть уверены, что знаете, что передаете на eval.
В PHP, Как вызвать функцию в строке?
Как разрешить php вызывать foo () и вставить строку возврата в эту строку?
$str="abcdefg foo() hijklmopqrst"; function foo() $replaced = preg_replace_callback("~([az]+)\(\)~", function ($m)< return $m[1](); >, $str);
$replaced == 'abcdefg bar hijklmopqrst';
Это позволит использовать любые строчные буквы в качестве имени функции. Если вам нужны другие символы, добавьте их в шаблон, т. [a-zA-Z_] .
Будьте ОЧЕНЬ осторожны, какие функции вы позволяете вызывать. Вы должны, по крайней мере, проверить, содержит ли $ m [1] функцию белого списка, чтобы не допускать удаленные атаки на ввод кода.
$allowedFunctions = array("foo", "bar" /*, . */); $replaced = preg_replace_callback("~([az]+)\(\)~", function ($m) use ($allowedFunctions) < if (!in_array($m[1], $allowedFunctions)) return $m[0]; // Don't replace and maybe add some errors. return $m[1](); >, $str);
Testrun на «abcdefg foo() bat() hijklmopqrst» выходы «abcdefg bar bat() hijklmopqrst» .
Оптимизация для подхода с использованием белого списка (динамическое построение шаблона из разрешенных имен функций, т. (foo|bar) .
$allowedFunctions = array("foo", "bar"); $replaced = preg_replace_callback("~(".implode("|",$allowedFunctions).")\(\)~", function ($m) < return $m[1](); >, $str);
Если вы вызываете метод некоторого класса, вы можете использовать нормальное расширение переменной. Например:
> $t = new thingie(); echo "thingie says: sayHello()>";
Обратите внимание, что требуются скобки вокруг вызова.
$str = "abcdefg".foo()."hijklmnopqrstuvwxyz";
Он будет вызывать функцию во время создания строки.
$foo = foo(); $str = "abcdefg hijklmopqrst";
function foo() < return 'Hi'; >$my_foo = 'foo'; echo "";
Вызов функций PHP внутри строк HEREDOC
В PHP описания строк HEREDOC действительно полезны для вывода блока html. Вы можете заставить его анализировать переменные, просто указав их на $, но для более сложного синтаксиса (например, $var [2] [3]) вы должны поместить свое выражение внутри <> фигурных скобок.
В PHP 5 можно фактически совершать вызовы функций внутри <> фигурных скобок внутри строки HEREDOC, но вам нужно пройти небольшую работу. Само имя функции должно храниться в переменной, и вы должны называть ее, как динамически называемую функцию. Например:
$fn = 'testfunction'; function testfunction() < return 'ok'; >$string = heredoc;
Как вы можете видеть, это немного более грязно, чем просто:
Есть другие способы, помимо первого примера кода, такие как выключение HEREDOC для вызова функции или изменение проблемы и выполнение чего-то вроде:
?> plain text and now a function:
Последнее имеет тот недостаток, что вывод напрямую помещается в выходной поток (если только я не использую буферизацию вывода), что может быть не тем, что я хочу.
Итак, суть моего вопроса: есть ли более элегантный способ приблизиться к этому?
Изменить на основе ответов: Конечно, похоже, что какой-то механизм шаблонов сделает мою жизнь намного проще, но это потребует от меня в основном инверсии моего обычного стиля PHP. Не то, что это плохо, но это объясняет мою инертность. Я собираюсь выяснить способы облегчения жизни, поэтому теперь я просматриваю шаблоны.
Я бы не использовал HEREDOC для этого лично. Это просто не делает для хорошей системы создания шаблонов. Весь ваш HTML заблокирован в строке, которая имеет несколько недостатков
- Нет опции для WYSIWYG
- Отсутствие кода для HTML из IDE
- Выход (HTML) заблокирован для логических файлов
- В конечном итоге вам придется использовать хаки как то, что вы пытаетесь сделать сейчас, чтобы добиться более сложных шаблонов, таких как цикл
Получить базовый механизм шаблонов или просто использовать PHP с включенными в него – это почему язык имеет разделители .
template_file.php
Hello World!'; > include('template_file.php');
Если вы действительно хотите сделать это, но немного проще, чем использовать класс, который вы можете использовать:
function fn($data) < return $data; >$fn = 'fn'; $my_string = EOT;
Не уверен, что вы считаете это более элегантным…
Попробуйте это (либо как глобальную переменную, либо создайте ее, когда вам это нужно):
Теперь любой вызов функции проходит через экземпляр $fn . Таким образом, существующую функцию testfunction() можно вызвать в heredoc с помощью testfunction()>
В основном мы обертываем все функции в экземпляр класса и используем метод PHP __call magic для сопоставления метода класса с фактической функцией, которая должна быть вызвана.
Я немного опоздал, но я случайно наткнулся на него. Для будущих читателей, вот что я бы сделал:
Я бы просто использовал выходной буфер. Таким образом, вы начинаете буферизацию с помощью ob_start(), затем включаете свой “файл шаблона” с любыми функциями, переменными и т.д. Внутри него, получаете содержимое буфера и записываете их в строку, а затем закрываете буфер. Затем вы использовали любые переменные, которые вам нужны, вы можете запускать любую функцию, и у вас все еще есть подсветка синтаксиса HTML, доступная в вашей среде IDE.
Файл шаблона:
Таким образом, script включает template_file.php в свой буфер, запускает любые функции/методы и назначает любые переменные на этом пути. Затем вы просто записываете содержимое буфера в переменную и выполняете то, что хотите с ней.
Таким образом, если вы не хотите повторять его на странице прямо в эту секунду, вам не нужно. Вы можете выполнить цикл и продолжить добавление в строку перед ее выходом.
Я думаю, что лучший способ пойти, если вы не хотите использовать механизм шаблонов.
Этот фрагмент определит переменные с именем ваших определенных функций в пределах userscope и привяжет их к строке, содержащей одно и то же имя. Позвольте мне продемонстрировать.
function add ($int) < return $int + 1; >$f=get_defined_functions();foreach($f[user]as$v) $string = heredoc;
Я думаю, что использование heredoc отлично подходит для генерации HTML-кода. Например, я считаю следующее почти полностью нечитаемым.
Однако для достижения простоты вам необходимо оценить функции перед тем, как начать. Я не считаю, что это такое ужасное ограничение, так как при этом вы заканчиваете выделение своих вычислений с дисплея, что обычно является хорошей идеей.
Я думаю, что следующее вполне читаемо:
$page_content = getPageContent(); print $page_content END;
К сожалению, несмотря на то, что это было хорошее предложение, которое вы задали в своем вопросе, чтобы связать функцию с переменной, в итоге она добавляет уровень сложности к коду, что не стоит, и делает код менее удобочитаемым, что является основным преимуществом heredoc.
Я бы посмотрел на Smarty в качестве механизма шаблона – я сам не пробовал никаких других, но это сделал мне хорошо.
Если вы хотите придерживаться своего текущего подхода без шаблонов, что плохого в буферизации вывода? Это даст вам гораздо большую гибкость, чем объявление переменных, которые являются именами имен вызываемых функций.
найдено приятное решение с функцией обертывания здесь: http://blog.nazdrave.net/?p=626
function heredoc($param) < // just return whatever has been passed to us return $param; >$heredoc = 'heredoc'; $string = Output the value of a constant: Static methods work just as well: 2 + 2 equals HEREDOC; // The same works not only with HEREDOC strings, // but with double-quoted strings as well: $string = "";
Для полноты вы также можете использовать черную магию !$ :
echo = date('Y-m-d H:i:s', strtotime('-1 month'))>. EOT;
Вы в значительной степени описываете, что происходит в движке шаблонов. Вы, очевидно, хорошо знаете php. Вы рассматривали возможность взглянуть на фактический шаблонный двигатель?
Немного поздно, но все же.
Это возможно в heredoc!
Вот хороший пример с использованием предложения @CJDennis:
function double($i) < return $i*2; >function triple($i) < return $i*3;>$tab = 'double'; echo " is $tab 5
"; $tab = 'triple'; echo " is $tab 5
";
Например, хорошее использование синтаксиса HEREDOC – это генерация огромных форм с отношением master-detail в базе данных. Можно использовать функцию HEREDOC внутри элемента управления FOR, добавляя суффикс после каждого имени поля. Это типичная задача на стороне сервера.
Ребята должны заметить, что он также работает с строками с двойными кавычками.
Интересный отзыв в любом случае.
Вызов функций PHP в строках HEREDOC
В PHP описания строк HEREDOC действительно полезны для вывода блока html. Вы можете заставить его анализировать переменные, просто указав их на $, но для более сложного синтаксиса (например, $var [2] [3]) вы должны поместить свое выражение внутри <> фигурных скобок. В PHP 5 можно фактически совершать вызовы функций внутри <> фигурных скобок внутри строки HEREDOC, но вам нужно пройти небольшую работу. Само имя функции должно храниться в переменной, и вы должны называть ее, как динамически называемую функцию. Например:
$fn = 'testfunction'; function testfunction() < return 'ok'; >$string = heredoc;
Есть другие способы, помимо первого примера кода, такие как выключение HEREDOC для вызова функции или изменение проблемы и выполнение чего-то вроде:
?> plain text and now a function:
Последнее имеет тот недостаток, что вывод напрямую помещается в выходной поток (если только я не использую буферизацию вывода), что может быть не тем, что я хочу. Итак, суть моего вопроса: есть ли более элегантный способ приблизиться к этому? Изменить на основе ответов: Конечно, похоже, что какой-то механизм шаблонов сделает мою жизнь намного проще, но это потребует от меня в основном инверсии моего обычного стиля PHP. Не то, что это плохо, но это объясняет мою инертность. Я собираюсь выяснить способы облегчения жизни, поэтому теперь я просматриваю шаблоны.
Это не совсем ответ на ваш вопрос, но, учитывая слабую поддержку вызовов функций в операторах heredoc, я обычно просто генерирую строки, которые мне понадобятся, прежде чем печатать heredoc. Затем я могу просто использовать что-то вроде Text Text Text в heredoc.$string1>