Czy w PHP jest sposób na umieszczenie stałej w ciągu znaków bez konkatenacji?
define('MY_CONSTANT', 42);
echo "This is my constant: MY_CONSTANT";
Czy w PHP jest sposób na umieszczenie stałej w ciągu znaków bez konkatenacji?
define('MY_CONSTANT', 42);
echo "This is my constant: MY_CONSTANT";
Odpowiedzi:
Nie.
W przypadku ciągów PHP nie ma sposobu, aby odróżnić dane łańcuchowe od stałych identyfikatorów. Dotyczy to wszystkich formatów ciągów w PHP, w tym heredoc.
constant()
jest alternatywnym sposobem na uzyskanie stałej, ale wywołanie funkcji nie może zostać umieszczone w łańcuchu bez konkatenacji.
define('ANIMAL','turtles'); $constant='constant'; echo "I like {$constant('ANIMAL')}";
Tak to jest (w pewnym sensie;)):
define('FOO', 'bar');
$test_string = sprintf('This is a %s test string', FOO);
Prawdopodobnie nie do tego dążyłeś, ale myślę, że technicznie nie jest to konkatenacja, ale podstawienie iz tego założenia zawiera stałą w łańcuchu bez konkatenacji .
Aby użyć stałych wewnątrz łańcuchów, możesz użyć następującej metody:
define( 'ANIMAL', 'turtles' );
$constant = 'constant';
echo "I like {$constant('ANIMAL')}";
Można umieścić dowolną nazwę funkcji w zmiennej i wywołać ją z parametrami wewnątrz łańcucha w cudzysłowie. Działa również z wieloma parametrami.
$fn = 'substr';
echo "I like {$fn('turtles!', 0, -1)}";
Produkuje
lubię żółwie
Możesz także korzystać z funkcji anonimowych pod warunkiem, że używasz PHP 5.3+.
$escape = function ( $string ) {
return htmlspecialchars( (string) $string, ENT_QUOTES, 'utf-8' );
};
$userText = "<script>alert('xss')</script>";
echo( "You entered {$escape( $userText )}" );
Zgodnie z oczekiwaniami tworzy prawidłowo zmieniony kod HTML.
Jeśli do tej pory masz wrażenie, że nazwa funkcji może być dowolna, tak nie jest, ponieważ tablica zwracająca wartość true po przekazaniu do is_callable
spowodowałaby błąd krytyczny, gdy zostanie użyta w ciągu:
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 )}" );
Ta praktyka jest nierozsądna, ale czasami skutkuje znacznie bardziej czytelnym kodem, więc to zależy od Ciebie - taka możliwość istnieje.
$_ = create_function('$a','return $a;'); $s = "I like {$_(ANIMAL)}"
. Wersja Thetaiko eliminuje potrzebę cytatów, a podkreślenie jest urocze.
define( 'FOO', 'bar');
$FOO = FOO;
$string = "I am too lazy to concatenate $FOO in my string";
Jeśli naprawdę chcesz uzyskać echo stałej bez konkatenacji, oto rozwiązanie:
define('MY_CONST', 300);
echo 'here: ', MY_CONST, ' is a number';
uwaga : w tym przykładzie echo przyjmuje szereg parametrów ( spójrz na przecinki ), więc nie jest to rzeczywiste połączenie
Echo zachowuje się jak funkcja, pobiera więcej parametrów, jest bardziej wydajne niż konkatenacja, ponieważ nie musi konkatenować, a potem odbijać, po prostu odbija wszystko bez konieczności tworzenia nowego obiektu łączonego String :))
EDYTOWAĆ
Również jeśli weźmiesz pod uwagę łączenie łańcuchów, przekazywanie łańcuchów jako parametry lub pisanie całych ciągów z " ," , (wersja z przecinkiem) jest zawsze najszybsza, następny idzie . (Konkatenacja z ' pojedynczymi cudzysłowami) a najwolniejsza metoda budowania ciągów używa podwójnych cudzysłowów " , ponieważ wyrażenia napisane w ten sposób muszą być oceniane w odniesieniu do zadeklarowanych zmiennych i funkcji.
Najłatwiej jest
define('MY_CONSTANT', 42);
$my_constant = MY_CONSTANT;
echo "This is my constant: $my_constant";
Inny sposób użycia (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;
Jak zauważyli inni, nie możesz tego zrobić. PHP ma funkcję, constant()
której nie można wywołać bezpośrednio w ciągu znaków, ale możemy łatwo obejść ten problem.
$constant = function($cons){
return constant($cons);
};
i podstawowy przykład użycia:
define('FOO', 'Hello World!');
echo "The string says {$constant('FOO')}";
$constant = 'constant';
zamiast definiować inną funkcję i będzie działać identycznie, ponieważ ta funkcja już istnieje.
Oto kilka alternatyw dla innych odpowiedzi, które wydają się być skoncentrowane głównie na sztuczce „{$}”. Chociaż nie ma gwarancji co do ich szybkości; to wszystko jest czysty cukier syntaktyczny. W tych przykładach przyjmiemy, że zdefiniowano poniższy zestaw stałych.
define( 'BREAD', 'bread' ); define( 'EGGS', 'eggs' ); define( 'MILK', 'milk' );
Używanie ekstraktu ()
To jest fajne, ponieważ wynik jest identyczny ze zmiennymi. Najpierw utwórz funkcję wielokrotnego użytku:
function constants(){ return array_change_key_case( get_defined_constants( true )[ 'user' ] ); }
Następnie wywołaj to z dowolnego zakresu:
extract( constants() );
$s = "I need to buy $bread, $eggs, and $milk from the store.";
Tutaj zmniejsza stałe, aby być łatwiejszym dla palców, ale możesz usunąć array_change_key_case (), aby zachować je bez zmian. Jeśli masz już sprzeczne nazwy zmiennych lokalnych, stałe ich nie zastąpią.
Używanie zamiany ciągów znaków
Ta metoda jest podobna do sprintf (), ale używa pojedynczego tokenu zastępczego i przyjmuje nieograniczoną liczbę argumentów. Jestem pewien, że istnieją lepsze sposoby, aby to zrobić, ale wybacz moją niezdarność i spróbuj skupić się na idei, która za tym stoi.
Tak jak poprzednio, tworzysz funkcję wielokrotnego użytku:
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;
}
Następnie wywołaj to z dowolnego zakresu:
$s = fill( 'I need to buy /, /, and / from the store.', BREAD, EGGS, MILK );
Możesz użyć dowolnego tokena zastępczego, takiego jak% lub #. Użyłem tutaj ukośnika, ponieważ wpisywanie jest nieco łatwiejsze.
To zabawne, że możesz użyć słowa kluczowego „const” jako nazwy swojej funkcji, aby zapobiec zaśmiecaniu przestrzeni nazw:
define("FOO","foo");
${'const'} = function($a){return $a;};
echo "{$const(FOO)}"; // Prints "foo"
echo const(FOO); // Parse error: syntax error, unexpected T_CONST
Możesz także użyć $ GLOBALS do propagowania funkcji 'const' w całym kodzie:
$GLOBALS['const'] = function($a){return $a;};
Nie jestem pewien, czy można go bezpiecznie używać w przyszłości. A co gorsza - nadal wygląda brzydko.
Myślę, że to odpowiada na pierwotne pytanie PO. Jedyną rzeczą jest to, że klucz indeksu globals wydaje się działać tylko z małymi literami.
define('DB_USER','root');
echo "DB_USER=$GLOBALS[db_user]";
Wynik:
DB_USER=root
an associative array containing references to all variables
.
$db_user = 'root';