4

Is there a way to 'prepare' a string for later interpolation (without using custom expansion function)?
For instance:

class Test {
    private static $STR_VAL = "the val is $v";

    public static function printVal($v) {
        echo self::$STR_VAL;
    }
}
9
  • Why do you need to pull the string out into a static member? Commented Jul 6, 2012 at 9:45
  • 1
    @Eric Why not? Separating the template strings from the values instead of writing every text inline somewhere in a mehod is not that uncommon. Commented Jul 6, 2012 at 9:48
  • This is just a simplified example. Imagine you need to use the string in 20 different places. Commented Jul 6, 2012 at 9:49
  • @cbaby: Isn't it the job of the Test::printVal to generate this string? The format string should appear in only one place - inside printVal. All other references should call printVal. Commented Jul 6, 2012 at 9:57
  • 1
    @Eric: And then you always need to search for printVal() to make changes to the template? Remember, that you may have much more such templates, that you may also place into a completely separate/different classes and they may be used by more than a single method. Commented Jul 6, 2012 at 10:25

2 Answers 2

8

sprintf()

class Test {
    private static $STR_VAL = "the val is %s";

    public static function printVal($v) {
        echo sprintf(self::$STR_VAL, $v);
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

echo sprintf() is an "antipattern". There is absolutely no reason that anyone should ever write echo sprintf() in any code for any reason -- it should be printf() every time.
FYI: My SEDE query: SELECT a.Id as [Post Link], a.CreationDate FROM Posts a INNER JOIN posts q ON q.id = a.parentid WHERE q.tags LIKE '%<##tag?php##>%' AND a.PostTypeId = 2 AND LEN(a.Body) < 300 AND a.Body LIKE '%echo sprintf(%' ORDER BY a.CreationDate ASC
@mickmackusa Who told you sprintf is an antipattern? In contrast I learned, that printf is an antipattern, because you loose control, when to output what. I non-linear applications -- which are nowadays pratically every application -- this can lead to strange issues and actually nobody wants "output everywhere!!111". That aside: sprintf and normal string interpolation are somehow similar, whereas sprintf is more powerful when handling data types. I'd really like to know, where your opinion comes from. Also: Your second comment seems to belong to a different post
The SEDE query is how I am finding all Stack Overflow answers that contain echo sprintf(). sprintf() isn't an antipattern -- I use that function all the time. What IS an antipattern is immediately echoing the returned value of sprintf(). When this is desired, printf() should be used. We should never see echo sprintf() in any code for any reason.
0

A solution if you want to preserve actual variable interpolation:

function interpolate_string($string, $vars) {
    extract($vars);
    return eval('return "' . addslashes($string) . '";');
}

class Test {
    //Note the single quote to prevent interpolation here
    private static $STR_VAL = 'the val is $v'; 

    public static function printVal($v) {
        echo interpolate_string(self::$STR_VAL, compact('v'));
    }
}

While I don't see any obvious attacks in this particular code, it should be noted that the use of eval() is a possible vector for code injection when dealing with untrusted strings.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.