Php 在不在对象上下文中时使用$this在数组中出错\u walk

Php 在不在对象上下文中时使用$this在数组中出错\u walk,php,Php,在类中使用带有闭包的array\u walk时,我遇到了一个奇怪的问题。这个问题在我使用php版本5.4.7的开发环境中不会出现,但在我的部署环境5.3.3中会出现 以下代码在我的生产环境中运行良好,但在我的部署环境中崩溃: <?php error_reporting(-1); Class TestArrayWalk { /** @var null|array */ protected $userInput = null;

在类中使用带有闭包的
array\u walk
时,我遇到了一个奇怪的问题。这个问题在我使用php版本5.4.7的开发环境中不会出现,但在我的部署环境5.3.3中会出现

以下代码在我的生产环境中运行良好,但在我的部署环境中崩溃:

<?php
    error_reporting(-1);

    Class TestArrayWalk
    {
        /** @var null|array */
        protected $userInput = null;

        /**
         * This expects to be passed an array of the users input from
         * the input fields.
         *
         * @param  array $input
         * @return void
         */
        public function setUserInput( array $input )
        {
            $this->userInput = $input;

            // Lets explode the users input and format it in a way that this class
            // will use for marking
            array_walk( $this->userInput, function( &$rawValue )
                {
                    $rawValue = array(
                        'raw' => $rawValue,
                        'words' => $this->splitIntoKeywordArray( $rawValue ),
                        'marked' => false,
                        'matched' => array()
                    );
                }
            );
        }

        public function getUserInput()
        {
            return $this->userInput;
        }

        protected function splitIntoKeywordArray( $input )
        {
            if ( ! is_string( $input )){ return array(); }
            return preg_split('/(\s|[\.,\/:;!?])/', $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
        }

    }


    $testArrayWalk = new TestArrayWalk();
    $testArrayWalk->setUserInput(
            array(
                'This is a test input',
                'This is another test input'
                )
        );

    var_dump( $testArrayWalk->getUserInput() );

如果您使用的是
PHP<5.4

public function setUserInput( array $input )
{
    $this->userInput = $input;
    $userInput_array = &$this->userInput;
    array_walk( &$userInput_array, function( &$rawValue ) use (&$userInput_array) {
        // use $userInput_array instaed of $this->userInput_array
    });
}

PHP手册中对此进行了描述:

Version Description 5.4.0 $this can be used in anonymous functions.
但请记住,您将无法访问私有和受保护的成员,因此您必须将
splitIntoKeywordArray
public

在类中的私有函数中定义的lambda函数也存在类似问题:

MyClass{
    private $str="doesn't work :-(";
    private function foo(){
        $bar=function(){
            echo $this->str; // triggers an "Using $this when not in object context" error
        };
        $bar();
    }
}
PHP 5.3.0解决方案:在父作用域(即私有函数)中声明变量$obj=&$this,并使用
use
语言构造将其传递给匿名函数。还要确保您访问的函数/变量具有
public
可见性(protected | private可能不起作用)


只要一个
foreach($this->userInput as&$rawValue){
就足够了(记住在循环之后
unset($rawValue);
)。哦,:“闭包现在支持$this.”,所以确实存在版本问题。尝试错误报告(2048)在这两种环境中,查看错误是否在这两种环境中都出现。如果是这样,可能是因为5.3和5.4Wrikken之间的错误报告行为更改是完全正确的,在闭包中对
$this
的支持只在PHP 5.4中添加了-服务器版本不支持这一点。@Wrikken谢谢。我仍然在学习PHP中的指针并且用
array\u walk
替换了我所有的
foreach
循环,这样我就可以利用匿名函数。我知道
foreach
可以实现这一点,但当时它使用array\u walk“工作”。这挽救了我的一天,值得称赞:)
MyClass{
    private $str="doesn't work :-(";
    private function foo(){
        $bar=function(){
            echo $this->str; // triggers an "Using $this when not in object context" error
        };
        $bar();
    }
}
MyClass{
    public $str="it just works :-)";
    private function foo(){
        $obj=&$this;
        $bar=function() use(&$obj){
            echo $this->str; // it works!
        };
        $bar();
    }
}