Как развернуть свойства объекта и локальные переменные из строки в PHP - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь получить конфигурацию шаблона сетевого устройства из mon go и использовать его для настройки устройства. Итак, у меня есть classDevice со свойствами, относящимися к устройствам, и методы CRUD для управления устройствами. Моя проблема здесь в том, что я не понимаю, как расширить свойства класса. Я пробовал поместить свойства в $vars с get_object_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();
?>

Это дает:

PHP Notice:  Undefined variable: this->ip in /home/pedro/test.php on line 23
PHP Notice:  Undefined variable: this->mode in /home/pedro/test.php on line 23
array(3) {
  [0]=>
  string(7) "set ip "
  [1]=>
  string(9) "set mode "
  [2]=>
  string(24) "set calculated attr test"
}

И это реальный код, где $ cfg - это Mon go возвращаемый объект, содержащий шаблон для применения там, где у меня есть локальные переменные и свойства объекта:

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

            }

Ответы [ 3 ]

2 голосов
/ 20 июня 2020

Потому что вы ищете $"this->ip" как строковую переменную вместо объекта $this->ip, если это имеет смысл. Попробуйте это:

foreach($variables[1] as $variable){
  $var = strpos($variable, '->') !== false ? $this->{end(explode('->', $variable))} : $$variable;
  $config = str_replace('$'.$variable, $var, $config);
}
0 голосов
/ 19 июня 2020

Проблема в том, что вы ошибочно принимаете форму переменной, читаемую человеком, за то, что она также читается машиной. Ваше регулярное выражение отфильтровывает переменную строку, которую вы читаете как 1 переменную, но для машины это переменная в переменной, например, переменная ip в переменной this. Дело в том, что когда вы извлекаете переменную с помощью регулярного выражения, вы получаете в основном 1 строку без объектно-ориентированного интеллекта.

Но, может быть, вам даже не нужно регулярное выражение? Если вы уже знаете переменные в шаблоне, почему бы не сделать это вот так:

<?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);
        var_dump($template);
        return $template;
    }
}

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

$test = new Device($data);
$test->configure();
?>

Или шаблон взят из базы данных? В этом случае может быть лучше не использовать строку $this->, а только сохранить $ip, чем пытаться ip и использовать property_exists в классе, чтобы проверить, присутствует ли свойство. Если да, замените строку в новом массиве.

0 голосов
/ 19 июня 2020

PHP выполняет только расширение встроенных переменных в двойных кавычках. Измените

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

на

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

Фигурные скобки не являются обязательными, но я считаю, что они делают код более читабельным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...