dongpu3792 2012-01-17 14:38
浏览 62
已采纳

使用__get或类似方法访问Array类型的类成员变量

Previously a class which I'm now rebuilding had a member variable $settings which was an array of settings, strangely enough.

class MyClass {
    public $settings = array();

    public function __construct() {
        if( empty( $this->settings ) ) {
            $this->settings = require( 'settings.php' ); // e.g. return array('setting1'=>4);
        }
    }
}

These settings were accessed by $object->settings['keyname'];

The means by which these keys are accessed has been moved into a method now. However, the application itself is riddled with calls to $object->settings['keyname']. I was wondering is there a way which I can catch any calls to the $settings member variable and return it using the new function.

I've looked at __get($name) but $name only contains settings rather than the array key which I need. What I'd need to pass would be the keyname to the my $object->get() method.

The reason I want to do this is so that I can trigger errors in a log file showing me where the deprecated calls to $object->settings[] are without breaking the application. Obviously setting $setting to private would give me lots of fatal errors and I could work through but there are multiple developers working on this codebase which I'd prefer not to break. If I could implement this as a temporary solution it'd help.

I realise there are repositories etc which we could use so that I could work on it separately and check it in afterwards but I'm looking for a quick, temporary solution as we're porting our codebase to Git soonish.

  • 写回答

2条回答 默认 最新

  • dongrandi8411 2012-01-17 14:54
    关注

    Totally possible:

    <?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'] . "
    ";
    

    Sure, it's hackish, and you probably don't want to keep this in your codebase, but for logging deprecated uses, it might be extremely helpful. Just log for a set period of time, and then replace the $this->settings = new Settings( ) with $this->settings = array( ).

    By the way, the output of that exact code is the following:

    berry@berry-pc:~/Desktop% php foo.php
    Setting 'foo' was called by file '/home/berry/Desktop/foo.php' on line 53
    bar
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探