รวมค่าคงที่ในสตริงโดยไม่ต้องต่อกัน


166

มีวิธีใน PHP ที่จะรวมค่าคงที่ในสตริงโดยไม่ต้องต่อกันหรือไม่?

define('MY_CONSTANT', 42);

echo "This is my constant: MY_CONSTANT";

12
ปรีชาบอกฉันว่า "นี่คือค่าคงที่ของฉัน: {MY_CONSTANT}" ควรใช้งานได้ มันไม่ได้ เพียงแค่วางสิ่งนี้ไว้ในกรณีที่มีคนคิดเหมือนกันกับฉัน
Mikael Lindqvist

คำตอบ:


148

เลขที่

ด้วย Strings ไม่มีทางที่ PHP จะบอกข้อมูลสตริงนอกเหนือจากตัวระบุคงที่ได้ สิ่งนี้เป็นรูปแบบสตริงใด ๆ ใน PHP รวมถึง heredoc

constant() เป็นวิธีทางเลือกในการรับค่าคงที่ แต่การเรียกใช้ฟังก์ชันไม่สามารถใส่ลงในสตริงได้โดยไม่ต้องต่อกัน

คู่มือเกี่ยวกับค่าคงที่ใน PHP


1
+1 อย่างไรก็ตามเนื่องจากเป็นคำตอบที่ถูกต้อง ก่อนอื่นฉันต้องการเขียนแบบเดียวกับคุณ แต่หลังจากอ่านของคุณฉันคิดว่าฉันต้องนำเสนอบางสิ่งที่แตกต่างออกไป;)
Felix Kling

3
ฮิฮิ! แต่ +1 ที่ดีสำหรับทุกคนสำหรับความคิดสร้างสรรค์ :)
Pekka

59
"การเรียกฟังก์ชั่นไม่สามารถใส่ลงในสตริง" ได้มันสามารถ:define('ANIMAL','turtles'); $constant='constant'; echo "I like {$constant('ANIMAL')}";
ยกระดับ

1
@Raveren ในขณะที่คนอื่นเสนอความแปรปรวนทางอ้อมการสร้างฟังก์ชั่นที่ไม่จำเป็นของคุณนั้นสั้นที่สุดและตรงประเด็นที่ต้องอาศัยฟังก์ชั่นตัวแปร จากหัวข้อทั้งหมดนี้ฉันได้ไปพร้อมกับโซลูชันเฉพาะของคุณ ฉันหวังว่าฉันจะสามารถ +1 ได้มากกว่าหนึ่งครั้ง
hndcrftd

4
ฉันเพิ่งจะชี้ให้เห็นว่าเป็นไปได้ไม่ได้ให้ความเห็นในทางที่ดีกว่า
raveren

111

ใช่มันเป็น (ในทางใดทางหนึ่ง)):

define('FOO', 'bar');

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

นี่อาจจะไม่ใช่สิ่งที่คุณกำลังเล็งหา แต่ผมคิดว่าในทางเทคนิคนี้ไม่ได้เรียงต่อกัน แต่ทดแทนและจากสมมติฐานนี้ก็มีอย่างต่อเนื่องในสตริงโดยไม่ต้องเชื่อมโยง


5
@Pekka: ฉันรู้ :-D (แค่คราวนี้ ... ;))
Felix Kling

1
:) @ แนวทางของ juraj.blahunka ยิ่งลับ ๆ ล่อ ๆ มันตอบคำถามด้วยจดหมาย แต่ไม่ใช่วิญญาณ :)
Pekka

2
@ blahunka: คำขวัญที่ดี เราอาจใช้มันทุกวัน
Alfabravo

57

ในการใช้ค่าคงที่ภายในสตริงคุณสามารถใช้วิธีการต่อไปนี้:

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 ที่ใช้ Escape อย่างเหมาะสมตามที่คาดไว้

ไม่อนุญาตให้ใช้อาร์เรย์โทรกลับ!

หากในตอนนี้คุณอยู่ภายใต้การแสดงผลที่ชื่อฟังก์ชันสามารถเรียกใช้ได้นั่นไม่ใช่กรณีดังกล่าวเนื่องจากอาร์เรย์ที่ส่งกลับค่าจริงเมื่อถูกส่งไปยัง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 )}" ); 

เก็บไว้ในใจ

แบบฝึกหัดนี้ไม่เหมาะสม แต่บางครั้งก็ส่งผลให้มีโค้ดที่อ่านได้มากขึ้นดังนั้นมันขึ้นอยู่กับคุณว่ามีความเป็นไปได้


1
นี่เป็นเคล็ดลับที่ยอดเยี่ยม! เช่นเดียวกับคำตอบอื่น ๆ ไม่ใช่การชนะครั้งใหญ่ในการต่อเรียงในแง่ของความพยายามและความสามารถในการอ่าน แต่ยินดีที่ได้รู้ $_ = create_function('$a','return $a;'); $s = "I like {$_(ANIMAL)}"ก็จะยิ่งเซ็กซี่เมื่อคุณทำสิ่งที่ชอบ รุ่นของ Thetaiko ลบความจำเป็นในการพูดและขีดล่างน่ารัก
Beejor

2
ฉันเห็นว่าสิ่งนี้มีประโยชน์สำหรับการสร้างเทมเพลตเอนจิ้น แต่ดูเหมือนจะไม่ใช้จริง ๆ
Mnebuerquo

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

4
นี่คือสิ่งที่ฉันใช้มากที่สุดเมื่อฉันมีสตริง SQL บ้า ๆ ที่จะเขียน นอกจากนี้ ... แฝง - ก้าวร้าวมากแค่ไหน? ;-)
Beejor

2
หนึ่งนี้มีเวทมนตร์น้อยที่สุดที่ค่าใช้จ่ายในการค้นหาซ้ำซ้อน
BrDaHa

ทางออกที่ดี ง่ายและรวดเร็ว
Roger Hill


13

หากคุณต้องการที่จะสะท้อนค่าคงที่โดยไม่ต้องต่อกันที่นี่เป็นทางออก:

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

หมายเหตุ : ในตัวอย่างนี้ echo ใช้พารามิเตอร์จำนวนหนึ่ง ( ดูเครื่องหมายจุลภาค ) ดังนั้นจึงไม่ใช่การต่อข้อมูลที่แท้จริง

Echo ทำหน้าที่เป็นฟังก์ชั่น, ใช้พารามิเตอร์มากกว่า, มีประสิทธิภาพมากกว่าการต่อข้อมูลเพราะมันไม่จำเป็นต้องต่อกันแล้วก็ก้อง, มันก็แค่ก้องทุกอย่างโดยไม่ต้องสร้าง String concatenated String ใหม่ :))

แก้ไข

นอกจากนี้ถ้าคุณพิจารณาconcatenatingสตริงสตริง passings เป็นพารามิเตอร์หรือเขียนสตริงทั้งหมดที่มี "The , (จุลภาครุ่น) อยู่เสมอเร็วที่สุดถัดไป. (เรียงต่อกันกับ'ราคาเดียว) และสตริงช้าที่สุดวิธีการสร้างคือการใช้คำพูดสอง" , เนื่องจากนิพจน์ที่เขียนด้วยวิธีนี้ต้องถูกประเมินเทียบกับตัวแปรและฟังก์ชันที่ประกาศไว้


11

คุณสามารถทำได้:

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

วิธีที่ง่ายที่สุดคือ

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;

ฉันคิดว่านี่เป็นทางออกที่ดี ในบางกรณีสตริงการเชื่อมต่อจะไม่ทำงานหากใช้ค่าคงที่โดยตรงภายใน
kta

5

ตามที่คนอื่น ๆ ได้ชี้ให้เห็นคุณไม่สามารถทำเช่นนั้น PHP มีฟังก์ชันconstant()ที่ไม่สามารถเรียกได้โดยตรงในสตริง แต่เราสามารถแก้ไขได้อย่างง่ายดาย

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

และตัวอย่างพื้นฐานเกี่ยวกับการใช้งาน:

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

คุณสามารถทำได้$constant = 'constant';แทนที่จะกำหนดฟังก์ชั่นอื่นและมันจะทำงานเหมือนกันเนื่องจากฟังก์ชั่นนั้นมีอยู่แล้ว
redreinard

2

ต่อไปนี้เป็นทางเลือกของคำตอบอื่น ๆ ซึ่งดูเหมือนจะเน้นไปที่เคล็ดลับ "{$}" เป็นส่วนใหญ่ แม้ว่าจะไม่รับประกันความเร็วของพวกเขา นี่คือน้ำตาลทรายบริสุทธิ์ทั้งหมด สำหรับตัวอย่างเหล่านี้เราจะถือว่ากลุ่มค่าคงที่ด้านล่างถูกกำหนด

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

ใช้สารสกัด ()
อันนี้ดีเพราะผลที่ได้จะเหมือนกับตัวแปร ก่อนอื่นให้คุณสร้างฟังก์ชั่นที่ใช้ซ้ำได้:

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 () แต่ใช้โทเค็นการแทนที่เดียวและยอมรับอาร์กิวเมนต์จำนวนไม่ จำกัด ฉันแน่ใจว่ามีวิธีที่ดีกว่าในการทำเช่นนี้ แต่ให้อภัย clunkiness ของฉันและพยายามเน้นความคิดที่อยู่เบื้องหลัง

ก่อนหน้านี้คุณสร้างฟังก์ชั่นที่ใช้ซ้ำได้:

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

คุณสามารถใช้โทเค็นการแทนที่ที่คุณต้องการเช่น% หรือ # ฉันใช้เครื่องหมายทับที่นี่เนื่องจากพิมพ์ได้ง่ายกว่าเล็กน้อย


0

มันสนุกที่คุณสามารถใช้คำสำคัญ 'const' เป็นชื่อสำหรับฟังก์ชันของคุณเพื่อป้องกันเนมสเปซ

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

คุณยังสามารถใช้ $ GLOBALS เพื่อเผยแพร่ฟังก์ชั่น 'const' ทั่วรหัส:

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

ไม่แน่ใจว่าปลอดภัยสำหรับการใช้ในอนาคต และสิ่งที่เลวร้ายกว่า - มันยังดูน่าเกลียด


-2

ฉันเชื่อว่านี่เป็นคำตอบของคำถามเดิมของ OP สิ่งเดียวคือคีย์ดัชนี globals ดูเหมือนว่าจะทำงานเป็นตัวพิมพ์เล็กเท่านั้น

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

เอาท์พุท:

DB_USER=root

1
นี้ดูเหมือนจะไม่ทำงาน (แม้ว่าคุณจะใช้ตัวพิมพ์ใหญ่อย่างต่อเนื่อง) $ GLOBALS an associative array containing references to all variablesคือ
har-wradim

คำตอบนี้ผิด วิธีเดียวที่สิ่งนี้อาจทำให้เกิดผลลัพธ์นั้นก็คือถ้าคุณอยู่ในสคริปท์ของคุณคุณก็จะทำได้$db_user = 'root';
Jeff Puckett
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.