如何在PHP中从字符串展开对象属性和局部变量

如何在PHP中从字符串展开对象属性和局部变量,php,class,Php,Class,我正在尝试从mongo获取网络设备模板配置,并使用它来配置设备。所以我有一个classDevice,它的属性与设备和CRUD方法有关,用于操作设备。我这里的问题是,我不知道如何扩展类属性。我尝试使用get\u object\u vars将属性放入$vars中,但结果是相同的空变量 下面是我尝试做的一个例子: <?php class Device { public $ip; public $mode; public function __construct($d

我正在尝试从mongo获取网络设备模板配置,并使用它来配置设备。所以我有一个classDevice,它的属性与设备和CRUD方法有关,用于操作设备。我这里的问题是,我不知道如何扩展类属性。我尝试使用
get\u object\u vars
将属性放入
$vars
中,但结果是相同的空变量

下面是我尝试做的一个例子:

<?php

class Device {

    public $ip;
    public $mode;

    public function __construct($data = false)
    {
        $this->ip = $data['ip'];
        $this->mode = $data['mode'];
    }

    public function configure(){
        if ($this->mode == 'bridge'){
            $localvar = 'test';
        }
        $template = array('0' => 'set ip $this->ip', '1' => 'set mode $this->mode', '2' => 'set calculated attr $localvar');
        $cfgexpanded = array();
        foreach ($template as $config) {
            preg_match_all('/\$([a-zA-Z0-9\-\>]+)/', $config, $variables, PREG_PATTERN_ORDER);
            foreach($variables[1] as $variable){
                $config = str_replace('$'.$variable, $$variable, $config);
            }
            array_push($cfgexpanded, $config);
        }
        var_dump($cfgexpanded);
    }
}

$data['ip'] = '1.2.3.4';
$data['mode'] = 'bridge';

$test = new Device($data);
$test->configure();
?>
这是真正的代码,$cfg是一个Mongo返回的对象,它包含要应用的模板,我有局部变量和对象属性:

            foreach ($cfg['cfg'] as $config) {
$$replace, $config));               
                preg_match_all('/\$([a-zA-Z0-9\-\>]+)/', $config, $variables, PREG_PATTERN_ORDER);
                foreach($variables[1] as $variable){
                    $config = str_replace('$'.$variable, $$variable, $config);
                }
                array_push($cfgexpanded, $config);

            }

PHP只在双引号中进行内联变量扩展。改变

    $template = array('0' => 'set ip $this->ip', '1' => 'set mode $this->mode', '2' => 'set calculated attr $localvar');


大括号不是绝对必要的,但我发现它们可以使代码更具可读性。

PHP只在双引号中进行内联变量扩展。改变

    $template = array('0' => 'set ip $this->ip', '1' => 'set mode $this->mode', '2' => 'set calculated attr $localvar');


大括号并不是绝对必要的,但我发现它们可以使代码更具可读性。

问题在于,您将人类可读的变量形式误认为也是机器可读的。您的正则表达式过滤掉您读取为1个变量的变量字符串,但对于机器来说是一个变量上的变量,例如
变量上的变量
ip
。问题是,当您通过正则表达式提取变量时,基本上得到1个字符串,而没有面向对象的智能

但也许你甚至不需要正则表达式?如果您已经知道模板中的变量,为什么不这样做



或者模板是否来自数据库?在这种情况下,最好不要使用
$this->
字符串,而只保留
$ip
,而不要尝试使用
ip
并在类上使用
属性\u exists
来检查该属性是否存在。如果是,请替换新数组中的字符串。

问题在于,您将变量的人类可读形式误认为也是机器可读的。您的正则表达式过滤掉您读取为1个变量的变量字符串,但对于机器来说是一个变量上的变量,例如
变量上的变量
ip
。问题是,当您通过正则表达式提取变量时,基本上得到1个字符串,而没有面向对象的智能

但也许你甚至不需要正则表达式?如果您已经知道模板中的变量,为什么不这样做



或者模板是否来自数据库?在这种情况下,最好不要使用
$this->
字符串,而只保留
$ip
,而不要尝试使用
ip
并在类上使用
属性\u exists
来检查该属性是否存在。如果是这样,请替换新数组中的字符串。

因为您将搜索
$“this->ip”
作为字符串变量,而不是对象
$this->ip
(如果有意义的话)。试试这个:

foreach($variables[1] as $variable){
  $var = strpos($variable, '->') !== false ? $this->{end(explode('->', $variable))} : $$variable;
  $config = str_replace('$'.$variable, $var, $config);
}

因为您将
$“this->ip”
搜索为字符串变量,而不是对象
$this->ip
,如果这有意义的话。试试这个:

foreach($variables[1] as $variable){
  $var = strpos($variable, '->') !== false ? $this->{end(explode('->', $variable))} : $$variable;
  $config = str_replace('$'.$variable, $var, $config);
}

是的,模板来自数据库,这段代码只是一个例子,但从答案来看可能不是最好的。在方法内部有一些计算,这就是为什么我需要解析局部变量+对象属性。我试过你说的,我想,使用get_object_vars将属性传递给数组,但结果是一样的。是的,模板来自数据库,这段代码只是一个例子,但从答案来看可能不是最好的。在方法内部有一些计算,这就是为什么我需要解析局部变量+对象属性。我试过你说的,我想,使用get_object_vars将属性传递给数组,但是结果是一样的。但是也有局部变量,我在方法中做了一些计算,所以我需要它们。我已经更新了答案。没有测试,但你应该得到我希望的想法。但是也有局部变量,我在方法中做了一些计算,所以我需要它们。我已经更新了答案。没有测试,但你应该得到我希望的想法。是的,在这个例子中,双引号起作用。但实际上,这个数组来自mongo数据库中的一个查询,并且已经带有双引号(正如var_dump所示),所以我认为这不是问题所在。是的,在本例中,双引号起到了作用。但实际上,这个数组来自mongo数据库中的一个查询,并且已经带有双引号(正如var_dump所示),所以我认为这不是问题所在。