Включить константу в строку без объединения - PullRequest
149 голосов
/ 05 февраля 2010

Есть ли в PHP способ включить константу в строку без объединения?

define('MY_CONSTANT', 42);

echo "This is my constant: MY_CONSTANT";

Ответы [ 12 ]

130 голосов
/ 05 февраля 2010

Нет.

При использовании Strings PHP не может отличить строковые данные от константных идентификаторов.Это относится к любому из строковых форматов в PHP, включая heredoc.

constant() - альтернативный способ получить константу, кроме вызова функциине может быть помещен в строку без конкатенации.

Руководство по константам в PHP

99 голосов
/ 05 февраля 2010

Да, это (в некотором роде;)):

define('FOO', 'bar');

$test_string = sprintf('This is a %s test string', FOO);

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

54 голосов
/ 14 марта 2014

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

define( 'ANIMAL', 'turtles' ); 
$constant = 'constant';

echo "I like {$constant('ANIMAL')}";


Как это работает?

Вы можете использовать любое имя строковой функции и произвольные параметры

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

$fn = 'substr';

echo "I like {$fn('turtles!', 0, -1)}";

Производит

Мне нравятся черепахи

Анонимные функции тоже

Вы также можете использовать анонимные функции, если вы используете PHP 5.3 +.

$escape   = function ( $string ) {
    return htmlspecialchars( (string) $string, ENT_QUOTES, 'utf-8' );
};
$userText = "<script>alert('xss')</script>";
echo( "You entered {$escape( $userText )}" );

Создает правильно экранированный html, как и ожидалось.

Массивы обратного вызова не допускаются!

Если к настоящему моменту у вас сложилось впечатление, что имя функции может быть любым вызываемым, это не так, поскольку массив, который возвращает true при передаче в is_callable, вызовет фатальную ошибку при использовании внутри строки:

class Arr
{

    public static function get( $array, $key, $default = null )
    {
        return is_array( $array ) && array_key_exists( $key, $array ) 
            ? $array[$key] 
            : $default;
    }
}

$fn = array( 'Arr', 'get' );
var_dump( is_callable( $fn ) ); // outputs TRUE

// following line throws Fatal error "Function name must be a string"
echo( "asd {$fn( array( 1 ), 0 )}" ); 

Имейте в виду,

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

20 голосов
/ 01 марта 2011
define( 'FOO', 'bar');  
$FOO = FOO;  
$string = "I am too lazy to concatenate $FOO in my string";
14 голосов
/ 08 февраля 2010
define('FOO', 'bar');
$constants = create_function('$a', 'return $a;');
echo "Hello, my name is {$constants(FOO)}";
12 голосов
/ 05 февраля 2010

Если вы действительно хотите отобразить константу без конкатенации вот решение:

define('MY_CONST', 300);
echo 'here: ', MY_CONST, ' is a number';

note : в этом примере echo принимает несколько параметров ( посмотрите на запятые ), поэтому это не настоящая конкатенация

Эхо ведет себя как функция, оно принимает больше параметров, оно более эффективно, чем конкатенация, потому что ему не нужно объединять, а затем эхо, оно просто повторяет все без необходимости создания нового объекта сцепления String:))

EDIT

Также, если вы рассматриваете объединение строк, передаваемых строк как параметров или запись целых строк с ", , (версия с запятой) ) всегда самый быстрый, затем идет . (объединение с ' одинарными кавычками), а самый медленный метод построения строки использует двойные кавычки ", потому что выражения, написанные таким образом должны быть оценены по объявленным переменным и функциям ..

11 голосов
/ 05 февраля 2010

Вы можете сделать:

define( 'FOO', 'bar' );

$constants = get_defined_constants(true); // the true argument categorizes the constants
$constants = $constants[ 'user' ]; // this gets only user-defined constants

echo "Hello, my name is {$constants['FOO']}";
5 голосов
/ 13 августа 2012

Как уже указывали другие, вы не можете этого сделать.PHP имеет функцию constant(), которую нельзя вызывать непосредственно в строке, но мы можем легко обойти это.

$constant = function($cons){
   return constant($cons);
};

и базовый пример ее использования:

define('FOO', 'Hello World!');
echo "The string says {$constant('FOO')}"; 
3 голосов
/ 04 октября 2016

Самый простой способ это

define('MY_CONSTANT', 42);

$my_constant = MY_CONSTANT;
echo "This is my constant: $my_constant";

Другой способ использования (s)printf

define('MY_CONSTANT', 42);

// Note that %d is for numeric values. Use %s when constant is a string    
printf('This is my constant: %d', MY_CONSTANT);

// Or if you want to use the string.

$my_string = sprintf('This is my constant: %d', MY_CONSTANT);
echo $my_string;
2 голосов
/ 05 июня 2015

Вот некоторые альтернативы другим ответам, которые, кажется, сосредоточены главным образом на уловке "{$}". Хотя нет никаких гарантий на их скорость; это все чистый синтаксический сахар. Для этих примеров мы будем предполагать, что набор констант ниже был определен.

define( 'BREAD', 'bread' ); define( 'EGGS', 'eggs' ); define( 'MILK', 'milk' );

Использование extract ()
Это хорошо, потому что результат идентичен переменным. Сначала вы создаете функцию многократного использования:

function constants(){ return array_change_key_case( get_defined_constants( true )[ 'user' ] ); }

Тогда позвоните из любой области:

extract( constants() );
$s = "I need to buy $bread, $eggs, and $milk from the store.";

Здесь константы проще для ваших пальцев, но вы можете удалить array_change_key_case (), чтобы оставить их как есть. Если у вас уже есть конфликтующие имена локальных переменных, константы не будут переопределять их.

Использование замены строки
Этот похож на sprintf (), но использует один маркер замены и принимает неограниченное количество аргументов. Я уверен, что есть более эффективные способы сделать это, но простите мое безрассудство и попытайтесь сосредоточиться на идее, стоящей за этим.

Как и прежде, вы создаете функцию многократного использования:

function fill(){
    $arr = func_get_args(); $s = $arr[ 0 ]; array_shift( $arr );
    while( strpos( $s, '/' ) !== false ){
        $s = implode( current( $arr ), explode( '/', $s, 2 ) ); next( $arr );
    } return $s;
}

Тогда звоните из любой области:

$s = fill( 'I need to buy /, /, and / from the store.', BREAD, EGGS, MILK );

Вы можете использовать любой заменяющий токен, например,% или #. Здесь я использовал косую черту, так как ее немного легче набрать.

...