Birleştirmeden dizeye sabiti dahil et


167

PHP'de bir dizeye birleştirme yapmadan bir sabit eklemenin bir yolu var mı?

define('MY_CONSTANT', 42);

echo "This is my constant: MY_CONSTANT";

12
Sezgi bana "Bu benim sabitim: {MY_CONSTANT}" 'ın çalışması gerektiğini söylüyor. Öyle değil. Birinin benimle aynı düşünmesi durumunda bunu buraya koyuyorum
Mikael Lindqvist

Yanıtlar:


148

Hayır.

Dizeler ile PHP'nin sabit tanımlayıcılar dışında dize verilerini söylemesinin bir yolu yoktur. Bu, heredoc dahil olmak üzere PHP'deki dize biçimlerinden herhangi biri için geçerlidir.

constant() bir sabiti tutmanın alternatif bir yoludur, ancak bir işlev çağrısı, birleştirme olmadan bir dizeye yerleştirilemez.

PHP sabitleri el kitabı


1
Şüphesiz doğru cevap olduğu için + 1'leyin. Öncelikle seninle aynı şeyi yazmak istedim, ama seninkini okuduktan sonra farklı bir şey sunmak zorunda olduğumu düşündüm;)
Felix Kling

3
Hehe! Ancak yaratıcılık için herkes için iyi bir +1. :)
Pekka

60
"işlev çağrısı bir dizgiye define('ANIMAL','turtles'); $constant='constant'; echo "I like {$constant('ANIMAL')}";
konamaz

1
@Raveren, diğerleri dolaylı varyasyonlar sunarken, gereksiz yere işlevler yaratırken, sizinki en kısa ve değişken işlevlere dayanan, PHP'nin az ve çok nadir kullanılan özelliğine dayanan nokta çözümüdür. Tüm bu iş parçacığından SİZİN özel çözüm ile gittim. Keşke bir kereden fazla + 1'leyebilseydim.
hndcrftd

4
Ben sadece mümkün olduğunu, hangi yolu daha iyi yorumladı işaret etti.
raveren

111

Evet (bir şekilde;)):

define('FOO', 'bar');

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

Muhtemelen amaçladığınız şey bu değil, ama bence, teknik olarak bu birleştirme değil, bir ikame ve bu varsayımdan, bir dizede birleştirmeden bir sabit içeriyor .


5
@Pekka: Biliyorum :-D (sadece bu sefer ...;))
Felix Kling

1
:) @ juraj.blahunka'nın yaklaşımı daha da sinsidir. Soruyu mektupla cevaplıyor, ama ruhunu değil. :)
Pekka

2
@blahunka: güzel slogan. Muhtemelen günlük olarak kullanıyoruz
Alfabravo

57

Dizelerin içindeki sabitleri kullanmak için aşağıdaki yöntemi kullanabilirsiniz:

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

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


Bu nasıl çalışıyor?

Herhangi bir dize işlevi adı ve rastgele parametreler kullanabilirsiniz

Bir değişkene herhangi bir işlev adı yerleştirilebilir ve çift tırnaklı bir dize içindeki parametrelerle çağırılabilir. Çoklu parametrelerle de çalışır.

$fn = 'substr';

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

üretir

kaplumbağaları severim

Anonim işlevler de

PHP 5.3+ çalıştırıyorsanız, anonim işlevleri de kullanabilirsiniz.

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

Beklendiği gibi düzgün kaçan html üretir.

Geri arama dizilerine izin verilmiyor!

Şimdiye kadar, işlev adının herhangi bir çağrılabilir olabileceği izlenimi altındaysanız, is_callablebir dizede kullanıldığında ölümcül bir hataya neden olacağı için, iletildiğinde true döndüren bir dizi söz konusu değildir :

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 )}" ); 

Aklında tut

Bu uygulama tavsiye edilmez, ancak bazen çok daha okunabilir bir kodla sonuçlanır, bu yüzden size kalmış - olasılık var.


1
Bu harika bir numara! Diğer cevaplar gibi, çaba ve okunabilirlik açısından birleştirme üzerinde gerçekten büyük bir kazanç değil, ama bilmek güzel. Böyle bir şey yaptığınızda daha da seksi olur $_ = create_function('$a','return $a;'); $s = "I like {$_(ANIMAL)}". Thetaiko'nun sürümü tırnak ihtiyacını ortadan kaldırıyor ve bir alt çizgi sevimli.
Beejor

2
Bunun bir şablon motoru oluşturmak için yararlı olduğunu görebiliyordum, ancak aslında kullanmak için çok sinsi görünüyor.
Mnebuerquo

21
define( 'FOO', 'bar');  
$FOO = FOO;  
$string = "I am too lazy to concatenate $FOO in my string";

4
Bir sürü çılgın SQL dizesi oluşturduğumda en çok kullandığım bu. Ayrıca ... pasif-agresif mi? ;-)
Beejor

2
Bu, gereksiz
görünmek

Harika bir çözüm. Basit ve hızlı.
Roger Hill

14
define('FOO', 'bar');
$constants = create_function('$a', 'return $a;');
echo "Hello, my name is {$constants(FOO)}";

13

Eğer gerçekten birleştirme olmadan sabit yankı istiyorsanız burada çözüm:

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

not : bu örnekte echo bir dizi parametre alır ( virgüllere bakın ), bu yüzden gerçek birleştirme değildir

Yankı bir işlev gibi davranır, daha fazla parametre alır, birleştirme işleminden daha etkilidir, çünkü birleştirmek ve daha sonra yankı yapmak zorunda değildir, yeni String birleştirilmiş nesne yaratmaya gerek kalmadan her şeyi yankılanır :))

DÜZENLE

Göz önünde Ayrıca birleştirerek olarak dizeleri, geçişleri dizeleri parametreleri veya yazma ile tüm dizeleri " , (virgül versiyonu) her zaman en hızlı, ertesi gider edilir . (İle birleştirme ' tek tırnak) ve yöntemi bina yavaş dize çift tırnak kullanıyor " , çünkü bu şekilde yazılan ifadelerin beyan edilen değişkenlere ve fonksiyonlara göre değerlendirilmesi gerekir.


11

Şunları yapabilirsiniz:

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']}";

6

En kolay yol

define('MY_CONSTANT', 42);

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

Kullanmanın başka bir yolu (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;

Bunu iyi bir çözüm olarak görüyorum. Bazı durumlarda, içinde doğrudan SABİT kullanılırsa bağlantı dizesi çalışmaz.
kta

5

Diğerlerinin işaret ettiği gibi bunu yapamazsınız. PHP, bir constant()dizede doğrudan çağrılamayan bir işleve sahiptir, ancak kolayca bu sorunu çözebiliriz.

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

ve kullanımı hakkında temel bir örnek:

define('FOO', 'Hello World!');
echo "The string says {$constant('FOO')}"; 

$constant = 'constant';Başka bir işlev tanımlamak yerine bunu yapabilirsiniz ve bu işlev zaten mevcut olduğundan, aynı şekilde çalışır.
1919'da redreinard

2

Aşağıda, çoğunlukla "{$}" numarasına odaklanmış gibi görünen diğer cevaplara bazı alternatifler verilmiştir. Hızları konusunda hiçbir garanti verilmese de; bunların hepsi saf sözdizimsel şekerdir. Bu örnekler için, aşağıdaki sabitler kümesinin tanımlandığını varsayacağız.

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

Extract () kullanılması
Bu, hoş bir sonuçtur çünkü sonuç değişkenlerle aynıdır. İlk önce yeniden kullanılabilir bir fonksiyon oluşturursunuz:

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

Sonra herhangi bir kapsamdan arayın:

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

Burada, sabitleri parmaklarınızda daha kolay olacak şekilde indirir, ancak olduğu gibi tutmak için array_change_key_case () öğesini kaldırabilirsiniz. Zaten çakışan yerel değişken adlarınız varsa, sabitler bunları geçersiz kılmaz.

Dize değiştirmeyi kullanma
Bu, sprintf () öğesine benzer, ancak tek bir değiştirme jetonu kullanır ve sınırsız sayıda bağımsız değişkeni kabul eder. Eminim bunu yapmanın daha iyi yolları vardır, ama becerikliğimi affedin ve arkasındaki fikre odaklanmaya çalışın.

Daha önce olduğu gibi, yeniden kullanılabilir bir işlev oluşturursunuz:

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;
}

Sonra herhangi bir kapsamdan arayın:

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

% Veya # gibi istediğiniz herhangi bir belirteç kullanabilirsiniz. Buradaki eğik çizgiyi kullandım çünkü yazmak biraz daha kolay.


0

Ad alanı çöplüğünü önlemek için 'const' anahtar sözcüğünü işleviniz için bir ad olarak kullanabilmeniz eğlencelidir:

define("FOO","foo");
${'const'} = function($a){return $a;};
echo "{$const(FOO)}"; // Prints "foo"
echo const(FOO); // Parse error: syntax error, unexpected T_CONST

'GLTAL' işlevini kodun her yerine yaymak için $ GLOBALS komutunu da kullanabilirsiniz:

$GLOBALS['const'] = function($a){return $a;};

İleride kullanmak için güvenli olduğundan emin değilim. Ve daha da kötüsü - hala çirkin görünüyor.


-2

Bunun OP'nin orijinal sorusuna cevap verdiğine inanıyorum. Tek şey, küresel dizin anahtarının sadece küçük harf gibi çalıştığıdır.

define('DB_USER','root');
echo "DB_USER=$GLOBALS[db_user]";

Çıktı:

DB_USER=root

1
Bu işe yaramaz gibi görünüyor (arka arkaya büyük harf kullansanız bile) $ GLOBALS an associative array containing references to all variables.
har-wradim

bu cevap yanlış. Bu muhtemelen bu çıktıyı üretmek için tek yolu senaryonuzda bir yerde de varsa$db_user = 'root';
Jeff Puckett
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.