Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用_get或类似工具访问数组类型的类成员变量_Php - Fatal编程技术网

Php 使用_get或类似工具访问数组类型的类成员变量

Php 使用_get或类似工具访问数组类型的类成员变量,php,Php,以前我现在重建的一个类有一个成员变量$settings,它是一个设置数组,这很奇怪 class MyClass { public $settings = array(); public function __construct() { if( empty( $this->settings ) ) { $this->settings = require( 'settings.php' ); // e.g. return arra

以前我现在重建的一个类有一个成员变量
$settings
,它是一个设置数组,这很奇怪

class MyClass {
    public $settings = array();

    public function __construct() {
        if( empty( $this->settings ) ) {
            $this->settings = require( 'settings.php' ); // e.g. return array('setting1'=>4);
        }
    }
}
这些设置由
$object->settings['keyname']访问

访问这些键的方法现在已经被移动到一个方法中。然而,应用程序本身充满了对
$object->settings['keyname']
的调用。我想知道是否有一种方法可以捕获对
$settings
成员变量的任何调用,并使用新函数返回它

我已经查看了
\u get($name)
,但是
$name
只包含
设置
,而不是我需要的数组键。我需要传递的是my
$object->get()
方法的键名

我这样做的原因是,我可以在日志文件中触发错误,该文件显示对
$object->settings[]
的不推荐调用的位置,而不会中断应用程序。显然,将$setting设置为private会给我带来很多致命错误,我可以解决这些错误,但是有多个开发人员正在处理这个代码库,我不想破坏它。如果我能把它作为一个临时解决方案来实施,它会有所帮助

我意识到我们可以使用一些存储库等,这样我就可以单独处理它,然后再将其签入,但我正在寻找一个快速、临时的解决方案,因为我们正在将代码库移植到Git soonish。

完全可能:

<?php
class Logger {
    public function log( $name, $backtrace ) {
        /**
         * $name is the name of the array index that was called on
         * MyClass->settings( ). $backtrace contains an array in which
         * you can find and determine which file has accessed that index,
         * and on which line.
         */
        $last = array_shift( $backtrace );
        $message = sprintf( "Setting '%s' was called by file '%s' on line %d",
            $name,
            $last['file'],
            $last['line']
        );

        echo $message;  

    }
}

class MyClass {
    protected $settings;

    public function __construct( ) {
        $this->settings = new Settings( new Logger( ), array( 'foo' => 'bar' ) );
    }

    public function __get( $name ) {
        if( $name === 'settings' ) {
            return $this->settings;
        }
    }
}

class Settings extends ArrayObject {
    protected $logger;
    protected $settings;
    public function __construct( Logger $logger, array $settings ) {
        $this->logger = $logger;
        parent::__construct( $settings );
    }

    public function offsetGet( $name ) {
        $backtrace = debug_backtrace( );
        $this->logger->log( $name, $backtrace );
        return parent::offsetGet( $name );
    }
}

$myClass = new MyClass( );
echo $myClass->settings['foo'] . "\n";

要查找脚本在“设置”中设置变量的位置,请执行以下操作:

我建议在你的
MyClass
类的构造函数和析构函数中加入一个小小的恶意代码。在构造函数中,扫描
$settings
并检查是否存在不推荐使用的值(将其保存在某个位置)。在析构函数中执行相同的检查,并交叉匹配两个结果。当您在销毁过程中有新变量时,您知道
$\u服务器['PHP\u SELF']
已经设置了它

要查找脚本访问它的位置,请执行以下操作:


很残酷,但我建议将所有不推荐的值转换为新值,然后看着事情停止工作。与修改类以使用记录器相比,您将花更少的时间跟踪损坏的内容并阅读“这曾经有效,但没有”投诉,正如Mikhail所说,最好的方法可能是只破坏应用程序并堵塞您创建的每个漏洞(前提是此更改一开始确实值得进行)。或者,如果您能够使用它。@MathewHall offsetGet($name)中的$name在代码示例中包含“foo”,而不是“settings”。它确实做到了问题中解释的事情。事实上,我把Settings类误认为是一个简单的记录器;为我的困惑道歉。老实说,只是我读得太快了。我在MyClass中看到了uu get,认为它只是返回$this->settings中的数组,而不是settings实例。代码很好。不知道
offsetGet
重载。非常整洁!回答得很好,非常准确。正是我想要的。非常感谢。
berry@berry-pc:~/Desktop% php foo.php
Setting 'foo' was called by file '/home/berry/Desktop/foo.php' on line 53
bar