PHP是否具有Python的模板字符串之类的功能?

发布于 2025-02-13 10:32:40 字数 419 浏览 1 评论 0原文

Python的功能称为模板字符串

>>> from string import Template
>>> s = Template('$who likes $what')
>>> s.substitute(who='tim', what='kung pao')
'tim likes kung pao'

我知道PHP允许您写作:

"Hello $person"

$ Person替换,但是模板可以在代码的各个部分中重复使用吗?

Python has a feature called template strings.

>>> from string import Template
>>> s = Template('$who likes $what')
>>> s.substitute(who='tim', what='kung pao')
'tim likes kung pao'

I know that PHP allows you to write:

"Hello $person"

and have $person substituted, but the templates can be reused in various sections of the code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

兰花执着 2025-02-20 10:32:41

另一个更简单的方法是:

$s = function ($vars) {
    extract($vars);
    return "$who likes $what";
};
echo $s(['who' => 'Tim', 'what' => 'King Pao']); // Tim likes King Pao

是的,PhpStorm会抱怨...

Another more simple approach would be this:

$s = function ($vars) {
    extract($vars);
    return "$who likes $what";
};
echo $s(['who' => 'Tim', 'what' => 'King Pao']); // Tim likes King Pao

And yes, PHPStorm will complain...

苏别ゝ 2025-02-20 10:32:41

我个人最喜欢 sprintf (或 vsprintf ,对于一系列参数)。它以预期的顺序将它们放置,根据需要胁迫类型,并具有更多高级功能。

示例:

$var = sprintf("%s costs %.2f dollars", "Cookies", 1.1);

这将导致价值cookies的成本1.10美元

有一个用于不同用例的printf功能的全家函数,所有这些功能都列在“参见”下。

非常通用:提供变量,数组组件,功能结果等的相同方法。

I personally most like sprintf (or vsprintf, for an array of arguments). It places them in the intended order, coerces types as needed, and has a lot more advanced features available.

Example:

$var = sprintf("%s costs %.2f dollars", "Cookies", 1.1);

This will result in the value Cookies cost 1.10 dollars.

There's an entire family of printf functions for different use cases, all listed under "See Also".

Very versatile: same methods for providing variables, array components, function results, etc.

压抑⊿情绪 2025-02-20 10:32:41

我做了一个工作来做你想做的事。我之所以成为“ Quck and-dirty”,是因为我没有太多时间来重构它,也许我将其上传到了我的github。

编辑:错误校正...

将其像

    formattemplatter(
                     '$who likes $what'
                     , array(
                               'who'  => 'Tim'
                             , 'what' => 'Kung Pao'
                     )
    );

变量一样使用,只能是[A-ZA-Z0-9_]。

 function formattemplater($string, $params) {
    // Determine largest string
    $largest = 0;
    foreach(array_keys($params) as $k) {
        if(($l=strlen($k)) > $largest) $largest=$l;
    }

    $buff   = '';

    $cp     = false;    // Conditional parenthesis
    $ip     = false;    // Inside parameter
    $isp    = false;    // Is set parameter

    $bl     = 1;    // buffer length
    $param  = '';   // current parameter

    $out    = '';  // output string
    $string .= '!';

    for($sc=0,$c=$oc='';isset($string{$sc});++$sc,++$bl) {
        $c = $string{$sc};

        if($ip) {
            $a = ord($c);

            if(!($a == 95 || (                  // underscore
                    ($a >= 48 && $a <= 57)      // 0-9
                    || ($a >= 65 && $a <= 90)   // A-Z
                    || ($a >= 97 && $a <= 122)  // a-z
                )
            )) {

                $isp = isset($params[$buff]);

                if(!$cp && !$isp) {
                    trigger_error(
                            sprintf(
                                    __FUNCTION__.': the parameter "%s" is not defined'
                                    , $buff
                            )
                            , E_USER_ERROR
                    );
                } elseif(!$cp || $isp) {
                    $out    .= $params[$buff];
                }

                $isp    = $isp && !empty($params[$buff]);
                $oc     = $buff = '';
                $bl     = 0;
                $ip     = false;
            }
        }

        if($cp && $c === ')') {
            $out .= $buff;

            $cp = $isp = false;
            $c  = $buff = '';
            $bl = 0;
        }

        if(($cp && $isp) || $ip)
            $buff .= $c;

        if($c === '
 && $oc !== '\\') {
            if($oc === '(')  $cp = true;
            else $out .= $oc;

            $ip   = true;
            $buff = $c = $oc = '';
            $bl   = 0;
        }

        if(!$cp && $bl > $largest) {
            $buff   = substr($buff, - $largest);
            $bl     = $largest;
        }

        if(!$ip && ( !$cp || ($cp && $isp))) {
            $out .= $oc;
            if(!$cp) $oc = $c;
        }
    }

    return $out;
}

I made a function to do what you want. i made it "quck-and-dirty" because i have not much time to refactorize it, maybe i upload it to my github.

EDIT: a bug correction...

Use it like

    formattemplatter(
                     '$who likes $what'
                     , array(
                               'who'  => 'Tim'
                             , 'what' => 'Kung Pao'
                     )
    );

Variables can be [a-zA-Z0-9_] only.

 function formattemplater($string, $params) {
    // Determine largest string
    $largest = 0;
    foreach(array_keys($params) as $k) {
        if(($l=strlen($k)) > $largest) $largest=$l;
    }

    $buff   = '';

    $cp     = false;    // Conditional parenthesis
    $ip     = false;    // Inside parameter
    $isp    = false;    // Is set parameter

    $bl     = 1;    // buffer length
    $param  = '';   // current parameter

    $out    = '';  // output string
    $string .= '!';

    for($sc=0,$c=$oc='';isset($string{$sc});++$sc,++$bl) {
        $c = $string{$sc};

        if($ip) {
            $a = ord($c);

            if(!($a == 95 || (                  // underscore
                    ($a >= 48 && $a <= 57)      // 0-9
                    || ($a >= 65 && $a <= 90)   // A-Z
                    || ($a >= 97 && $a <= 122)  // a-z
                )
            )) {

                $isp = isset($params[$buff]);

                if(!$cp && !$isp) {
                    trigger_error(
                            sprintf(
                                    __FUNCTION__.': the parameter "%s" is not defined'
                                    , $buff
                            )
                            , E_USER_ERROR
                    );
                } elseif(!$cp || $isp) {
                    $out    .= $params[$buff];
                }

                $isp    = $isp && !empty($params[$buff]);
                $oc     = $buff = '';
                $bl     = 0;
                $ip     = false;
            }
        }

        if($cp && $c === ')') {
            $out .= $buff;

            $cp = $isp = false;
            $c  = $buff = '';
            $bl = 0;
        }

        if(($cp && $isp) || $ip)
            $buff .= $c;

        if($c === '
 && $oc !== '\\') {
            if($oc === '(')  $cp = true;
            else $out .= $oc;

            $ip   = true;
            $buff = $c = $oc = '';
            $bl   = 0;
        }

        if(!$cp && $bl > $largest) {
            $buff   = substr($buff, - $largest);
            $bl     = $largest;
        }

        if(!$ip && ( !$cp || ($cp && $isp))) {
            $out .= $oc;
            if(!$cp) $oc = $c;
        }
    }

    return $out;
}
悲念泪 2025-02-20 10:32:41

只是为了完整的目的:还有 Heredoc

$template = fn( $who, $what ) => <<<EOT
    $who likes $what
EOT;

echo( $template( 'tim', 'kung pao' ) );

输出:

tim likes kung pao

Sidenotes:

  • 您会以自己喜欢的语言突出显示(如果配置正确)。只需将EOT(从上面的示例)代替您喜欢的任何内容(EC HTML,SQL,PHP,...)。
  • 带有卷曲括号{$ data ['Who'']}的逃脱数组。访问$ data-&gt; Who无括号的objekts。
  • arrow functions 喜欢fn($ a)=&gt; $ a自PHP 7.4以来可用。您可以编写函数($ a){返回$ a;},如果您使用的是php&lt; 7.4。

Just for the sake of completeness: there is also Heredoc.

$template = fn( $who, $what ) => <<<EOT
    $who likes $what
EOT;

echo( $template( 'tim', 'kung pao' ) );

Outputs:

tim likes kung pao

Sidenotes:

  • You get highlighting in your favourite language (if properly configured). Just substitute EOT (from the sample above) with whatever you like (e.c. HTML, SQL, PHP, ...).
  • Escape arrays with curly braces {$data['who']}. Accessing objekts like $data->who works without braces.
  • Arrow functions like fn($a)=>$a are available since PHP 7.4. You can write function($a){return $a;} if you are using PHP<7.4.
流云如水 2025-02-20 10:32:41

另一个选择是将消息形式用作功能或对象:

<?php
echo msgfmt_format_message('en_GB', 'Tom has {0, plural, =0{no cat} =1{a cat} other{# cats}}', [0]), "\n";
echo msgfmt_format_message('en_GB', 'Tom has {0, plural, =0{no cat} =1{a cat} other{# cats}}', [1]), "\n";
echo msgfmt_format_message('en_GB', 'Tom has {0, plural, =0{no cat} =1{a cat} other{# cats}}', [2]), "\n";
    
echo msgfmt_format_message('de', 'Tom hat {cat, plural, =0{keine Katze} =1{eine Katze} other{# Katzen}} und {dog} Hunde', ['cat'=>12345, 'dog'=>-5.23]), "\n";
    
echo MessageFormatter::formatMessage('de', 'Tom hat {cat, plural, =0{keine Katze} =1{eine Katze} other{# Katzen}} und {dog,number} Hunde', ['cat'=>12, 'dog'=>-5.23]), "\n";
    
$fmt = new MessageFormatter('de', 'Tom hat {cat, plural, =0{keine Katze} =1{eine Katze} other{# Katzen}} und {dog,number} Hunde');
echo $fmt->format(['cat'=>12, 'dog'=>-5.23]);

输出:

  • 汤姆没有猫
  • 汤姆有一只猫
  • 汤姆有2个猫
  • 12.345 katzen und
  • 帽子
  • 汤姆 -5.23 5,23 Hunde

An other option is to use MessageFormatter as function or object:

<?php
echo msgfmt_format_message('en_GB', 'Tom has {0, plural, =0{no cat} =1{a cat} other{# cats}}', [0]), "\n";
echo msgfmt_format_message('en_GB', 'Tom has {0, plural, =0{no cat} =1{a cat} other{# cats}}', [1]), "\n";
echo msgfmt_format_message('en_GB', 'Tom has {0, plural, =0{no cat} =1{a cat} other{# cats}}', [2]), "\n";
    
echo msgfmt_format_message('de', 'Tom hat {cat, plural, =0{keine Katze} =1{eine Katze} other{# Katzen}} und {dog} Hunde', ['cat'=>12345, 'dog'=>-5.23]), "\n";
    
echo MessageFormatter::formatMessage('de', 'Tom hat {cat, plural, =0{keine Katze} =1{eine Katze} other{# Katzen}} und {dog,number} Hunde', ['cat'=>12, 'dog'=>-5.23]), "\n";
    
$fmt = new MessageFormatter('de', 'Tom hat {cat, plural, =0{keine Katze} =1{eine Katze} other{# Katzen}} und {dog,number} Hunde');
echo $fmt->format(['cat'=>12, 'dog'=>-5.23]);

Output:

  • Tom has no cat
  • Tom has a cat
  • Tom has 2 cats
  • Tom hat 12.345 Katzen und -5.23 Hunde
  • Tom hat 12 Katzen und -5,23 Hunde
  • Tom hat 12 Katzen und -5,23 Hunde
小耗子 2025-02-20 10:32:40

您可以使用这样的模板字符串:

$name = "Maria";
$info["last_name"] = "Warner";

echo "Hello {$name} {$info["last_name"]}";

这将回荡您好Maria Warner

You can use template strings like this:

$name = "Maria";
$info["last_name"] = "Warner";

echo "Hello {$name} {$info["last_name"]}";

This will echo Hello Maria Warner.

南…巷孤猫 2025-02-20 10:32:40

您也可以使用 strtr

$template = '$who likes $what';

$vars = array(
  '$who' => 'tim',
  '$what' => 'kung pao',
);

echo strtr($template, $vars);

输出:输出:

tim likes kung pao

You could also use strtr:

$template = '$who likes $what';

$vars = array(
  '$who' => 'tim',
  '$what' => 'kung pao',
);

echo strtr($template, $vars);

Outputs:

tim likes kung pao
爱你不解释 2025-02-20 10:32:40

我认为有很多方法可以做到这一点...但这想到了。

$search = array('%who%', '%what_id%');
$replace = array('tim', 'kung pao');
$conference_target = str_replace(
    $search,
    $replace,
    "%who% likes %what%"
);

,我们在框架中甚至使用 vsprintf

class Helper_StringFormat {

    public static function sprintf($format, array $args = array()) {

        $arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

        for ($pos = 0; preg_match('/(?<=%)\(([a-zA-Z_]\w*)\)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
            $arg_pos = $match[0][2];
            $arg_len = strlen($match[0][0]);
            $arg_key = $match[1][0];

            if (! array_key_exists($arg_key, $arg_nums)) {
                user_error("sprintfn(): Missing argument '${arg_key}'", E_USER_WARNING);
                return false;
            }
            $format = substr_replace($format, $replace = $arg_nums[$arg_key] . '

哈 它来自 sprintf页面

=“ http://www.php.net/manual/fr/function.sprintf.php#94608 ”

sprintfn('second: %(second)s ; first: %(first)s', array(
    'first' => '1st',
    'second'=> '2nd'
));

href 强>
这是要完成您想要的更新...尽管

class Helper_StringFormat {

    public static function sprintf($format, array $args = array()) {
        $arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

        for ($pos = 0; preg_match('/(?<=%)\(([a-zA-Z_][\w\s]*)\)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
            $arg_pos = $match[0][1];
            $arg_len = strlen($match[0][0]);
            $arg_key = $match[1][0];

            if (! array_key_exists($arg_key, $arg_nums)) {
                user_error("sprintfn(): Missing argument '${arg_key}'", E_USER_WARNING);
                return false;
            }
            $format = substr_replace($format, $replace = $arg_nums[$arg_key] . '

输出
尚未完全测试
现在空间进行稍作修改。

, $arg_pos, $arg_len); $pos = $arg_pos + strlen($replace); } return vsprintf($format, array_values($args)); } }

哈 它来自 sprintf页面

=“ http://www.php.net/manual/fr/function.sprintf.php#94608 ”


href 强>
这是要完成您想要的更新...尽管


输出
尚未完全测试
现在空间进行稍作修改。

, $arg_pos, $arg_len); $pos = $arg_pos + strlen($replace); // skip to end of replacement for next iteration } return vsprintf($format, array_values($args)); } } $str = "%(my var)s now work with a slight %(my var2)s"; $repl = array("my var" => "Spaces", "my var2" => "modification."); echo Helper_StringFormat::sprintf($str, $repl);

输出
尚未完全测试
现在空间进行稍作修改。

, $arg_pos, $arg_len); $pos = $arg_pos + strlen($replace); } return vsprintf($format, array_values($args)); } }

哈 它来自 sprintf页面

=“ http://www.php.net/manual/fr/function.sprintf.php#94608 ”

href 强>
这是要完成您想要的更新...尽管

输出
尚未完全测试
现在空间进行稍作修改。

I think there are a bunch of ways to do this... but this comes to mind.

$search = array('%who%', '%what_id%');
$replace = array('tim', 'kung pao');
$conference_target = str_replace(
    $search,
    $replace,
    "%who% likes %what%"
);

Ha, we even had one in our framework using vsprintf:

class Helper_StringFormat {

    public static function sprintf($format, array $args = array()) {

        $arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

        for ($pos = 0; preg_match('/(?<=%)\(([a-zA-Z_]\w*)\)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
            $arg_pos = $match[0][2];
            $arg_len = strlen($match[0][0]);
            $arg_key = $match[1][0];

            if (! array_key_exists($arg_key, $arg_nums)) {
                user_error("sprintfn(): Missing argument '${arg_key}'", E_USER_WARNING);
                return false;
            }
            $format = substr_replace($format, $replace = $arg_nums[$arg_key] . '

Which looks like it came from the sprintf page

This allows for calls like:

sprintfn('second: %(second)s ; first: %(first)s', array(
    'first' => '1st',
    'second'=> '2nd'
));

UPDATE
Here is an update to do what you want... not fully tested though

class Helper_StringFormat {

    public static function sprintf($format, array $args = array()) {
        $arg_nums = array_slice(array_flip(array_keys(array(0 => 0) + $args)), 1);

        for ($pos = 0; preg_match('/(?<=%)\(([a-zA-Z_][\w\s]*)\)/', $format, $match, PREG_OFFSET_CAPTURE, $pos);) {
            $arg_pos = $match[0][1];
            $arg_len = strlen($match[0][0]);
            $arg_key = $match[1][0];

            if (! array_key_exists($arg_key, $arg_nums)) {
                user_error("sprintfn(): Missing argument '${arg_key}'", E_USER_WARNING);
                return false;
            }
            $format = substr_replace($format, $replace = $arg_nums[$arg_key] . '

OUTPUT
Spaces now work with a slight modification.

, $arg_pos, $arg_len); $pos = $arg_pos + strlen($replace); } return vsprintf($format, array_values($args)); } }

Which looks like it came from the sprintf page

This allows for calls like:


UPDATE
Here is an update to do what you want... not fully tested though


OUTPUT
Spaces now work with a slight modification.

, $arg_pos, $arg_len); $pos = $arg_pos + strlen($replace); // skip to end of replacement for next iteration } return vsprintf($format, array_values($args)); } } $str = "%(my var)s now work with a slight %(my var2)s"; $repl = array("my var" => "Spaces", "my var2" => "modification."); echo Helper_StringFormat::sprintf($str, $repl);

OUTPUT
Spaces now work with a slight modification.

, $arg_pos, $arg_len); $pos = $arg_pos + strlen($replace); } return vsprintf($format, array_values($args)); } }

Which looks like it came from the sprintf page

This allows for calls like:

UPDATE
Here is an update to do what you want... not fully tested though

OUTPUT
Spaces now work with a slight modification.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文