PHP static properties in double quotes
Asked Answered
M

10

49

How can I get PHP to evaluate a static variable in double quotes?

I want to do something like this:

log("self::$CLASS $METHOD entering");

I've tried all sorts of {} combos to get the variable value of self::$CLASS, but nothing has worked. I've currently settled with string concatenation but it is a pain to type:

log(self::$CLASS . " $METHOD entering");
Mulkey answered 12/8, 2009 at 15:53 Comment(5)
log(self::$CLASS . " $METHOD entering"); is ONE extra character to type instead of log("self::$CLASS $METHOD entering"); .. this is a pain?Maestro
It's not that bad, but the other one is slightly easier to read and type. :) I was just wondering if there was an alternative if you weren't concerned with optimization.Mulkey
@Scott: Discouragement is not an answerPowerboat
@Powerboat it's not an answer, it's just the answer.Dysplasia
Sorry, but you can do this. Look at my post here: https://mcmap.net/q/356736/-proper-way-to-access-a-static-variable-inside-a-string-with-a-heredoc-syntax/39778415#39778415Fy
P
49

Sorry, you can't do that. It only works for simple expressions. See here.

Pinnatiped answered 12/8, 2009 at 16:11 Comment(1)
"Since { can not be escaped, this syntax will only be recognised when the $ immediately follows the {." If I understand this correctly, " {self::$METHOD} " won't work because the $ character must directly follow the left curly brace.Mulkey
P
10

Unfortunately there is no way how to do this yet. Example in one of answers here will not work, because {${self::$CLASS}} will not returns content of self::$CLASS, but will returns content of variable with name in self::$CLASS.

Here is an example, which does not returns myvar, but aaa:

$myvar = 'aaa';
self::$CLASS = 'myvar';
echo "{${self::$CLASS}}";
Philana answered 24/9, 2013 at 14:24 Comment(0)
L
7

Use an anonymous identity function stored in a variable. This way you will have $ immediately after {:

$I = function($v) { return $v; };
$interpolated = "Doing {$I(self::FOO)} with {$I(self::BAR)}";

(I am using class constants in this example but this will work with static variables too).

Lolanthe answered 27/5, 2018 at 16:40 Comment(0)
O
4

I don’t know the answer to your question, but you can show the class name and method using the __METHOD__ magic constant.

Orfurd answered 12/8, 2009 at 15:56 Comment(1)
Thanks. This was helpful. I'm moving over from Java and haven't had a chance to dig into the magic constants. I'll use these instead of defining class and method variables.Mulkey
G
1

I know this is an old question but I find it odd that noone has suggested the [sprintf][1] function yet.

say:

<?php

class Foo {

    public static $a = 'apple';

}

you would use it with:

echo sprintf( '$a value is %s', Foo::$a );

so on your example its:

log(
    sprintf ( ' %s $METHOD entering', self::$CLASS )
);
Grammar answered 30/9, 2018 at 18:49 Comment(3)
While I agree with you in principle, OP is asking specifically about string interpolation in double quotes. Not sprintf.Persist
@Persist OP said: I've currently settled with string concatenation but it is a pain to typeGrammar
Of course, echo sprintf() should never be combined for any reason. If you want to print the formatted string, you simply call printf().Unbated
F
1
<?php

class test {
    public $static = 'text';
    public $self = __CLASS__;
    // static Method
    static function author() {
        return "Frank Glück";
    }
    // static variable
    static $url = 'https://www.dozent.net';
    public function dothis() {
       $self = __CLASS__;
       echo <<<TEST
           
           {${!${''}=static::author()}} // works
           {$self::author()}            // works
           {$this->self::author()}      // do/don't works but with notice
           ${!${''}=self::author()}     // works
           
           {${$this->self}}::author()}} // do/don't works but with notice
           ${${self::author()}}         // do/don't works but with notice
           ${@${self::author()}}        // works but with @ !
           
TEST;
    }
}

$test = 'test'; // this is the trick, put the Classname into a variable

echo "{$test::author()} {$$test::$url}";
echo <<<HTML
<div>{$test::author()}</div>
<div>{$$test::$url}</div>
HTML;

$test = new test();
$test->dothis();

Output for 8.2.14 - 8.2.17, 8.3.0 - 8.3.4:

Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in /in/uGdhi on line 18

Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in /in/uGdhi on line 21

Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in /in/uGdhi on line 22
Frank Glück https://www.dozent.net<div>Frank Glück</div>
<div>https://www.dozent.net</div>
Warning: Undefined variable $test in /in/uGdhi on line 21

Warning: Undefined variable $Frank Glück in /in/uGdhi on line 22
           
           Frank Glück // works
           Frank Glück            // works
           Frank Glück      // do/don't works but with notice
           Frank Glück     // works
           
           ::author()}} // do/don't works but with notice
           Frank Glück         // do/don't works but with notice
           Frank Glück        // works but with @ !

Output for 8.1.0 - 8.1.27 (and older)

Frank Glück https://www.dozent.net<div>Frank Glück</div>
<div>https://www.dozent.net</div>
Warning: Undefined variable $test in /in/uGdhi on line 21

Warning: Undefined variable $Frank Glück in /in/uGdhi on line 22
           
           Frank Glück // works
           Frank Glück            // works
           Frank Glück      // do/don't works but with notice
           Frank Glück     // works
           
           ::author()}} // do/don't works but with notice
           Frank Glück         // do/don't works but with notice
           Frank Glück        // works but with @ !
Fy answered 12/11, 2020 at 8:43 Comment(2)
it's doesn't work by the way, not don't works.Plumate
I update the Code an add the output from PHP. So if it not work, you do some wrong.Fy
A
1

The way I've accomplished it is by setting a variable to the static class itself:

$self = self::class;

Then I can interpolate it:

$string = "This is: {$self::property}";
Auctorial answered 10/2 at 12:36 Comment(0)
S
0
//define below
function EXPR($v) { return $v; }
$E = EXPR;

//now you can use it in string
echo "hello - three is equal to $E(1+2)";
Spermatophyte answered 21/7, 2020 at 11:31 Comment(0)
W
-3

Just live with the concatenation. You'd be surprised how inefficient variable interpolation in strings can be.

And while this could fall under the umbrella of pre-optimization or micro-optimization, I just don't think you actually gain any elegance in this example.

Personally, if I'm gonna make a tiny optimization of one or the other, and my choices are "faster" and "easier to type" - I'm gonna choose "faster". Because you only type it a few times, but it's probably going to execute thousands of times.

Westernize answered 12/8, 2009 at 16:19 Comment(4)
Discouragement is not an answer.Powerboat
Looks like that permalink is anything but.Heiney
That discussion of string interpolation may not still be true: according to Rasmus Lerdorf (via Twitter), it's a 1 opcode vs tmp var trade-off, and performance is similar.Ireland
article talks claims interpolation is inefficient. provides no benchmarks whatsoever -_-Elenor
M
-5

Yes this can be done:

log("{${self::$CLASS}} $METHOD entering");
Moreville answered 12/8, 2013 at 14:47 Comment(1)
Yes, it is allowed, but it doesn't achieve the desired effect -- it'll treat self::$CLASS as a variable name; so if self::$CLASS == 'foo' then you'll end up with {$foo}, and not 'foo' like you might be expecting.Confessor

© 2022 - 2024 — McMap. All rights reserved.