【问题标题】:Do all variables in methods need to be object properties? (PHP)方法中的所有变量都需要是对象属性吗? (PHP)
【发布时间】:2011-05-15 21:09:24
【问题描述】:

我正在学习 OO PHP,并且正在尝试直接掌握一些编码实践。这是我用于错误(和异常)处理的一些代码的精简版本:

final class MyErrorExceptionHandler {

    private $level = array(); // error levels to be handled as standard errors
    private $path = array(); // full path to file
    private $path_short; // filename plus working dir

    public function myErrorHandler($severity, $message, $file, $line) {
        if (error_reporting() & $severity) { // error code is included in error_reporting
            $this->level = array(E_WARNING => 'warning',
                E_NOTICE => 'notice',
                E_USER_WARNING => 'user warning',
                E_USER_NOTICE => 'user notice');
            if (array_key_exists($severity, $this->level)) { // handle as standard error
                /*$this->severity = $severity;
                $this->message = $message;
                $this->file = $file;
                $this->line = $line;*/
                $this->printMessage($severity, $message, $file, $line);
            } else { // fatal: E_USER_ERROR or E_RECOVERABLE_ERROR use php's ErrorException converter
                throw new ErrorException($message, 0, $severity, $file, $line);
            }
        }
    } // fn myErrorHandler

    private function printMessage($severity, $message, $file, $line) {
        echo ucfirst($this->level[$severity]) . ': ' . $message;
        $this->shortenPath($file);
        echo ' in ' . $this->path_short . ' on line ' . $line;
    } // fn printMessage

    private function shortenPath($file) {
        $this->path_short = $file;
        $this->path = explode(DIRECTORY_SEPARATOR, $file);
        if (count($this->path) > 2) { // shorten path to one dir, if more than one dir
            $this->path_short = array_pop($this->path); // filename
            $this->path_short = end($this->path) . DIRECTORY_SEPARATOR . $this->path_short; // dir+file
        }
    } // fn shortenPath

} // cl MyErrorExceptionHandler

这个问题的标题可能有点偏离,因为我不是 100% 了解术语。基本上我想弄清楚一些事情。

  1. $level$path 显式声明为数组是否正确?
  2. 是否应按原样声明$level(并设为$this->level)?如果是这样,我是否在明智的地方分配了它的值(E_WARNING 等)?构造函数(此处未显示)会是更明智的选择吗?
  3. 注意myErrorHandler() 中的注释块。最初我在类的顶部声明了所有这些属性,然后在没有任何参数的情况下调用$this->printMessage()。哪种方法更正确?如果我保持代码不变,我是否想在printMessage() 中使用$this->severity = $severity 等?
  4. 那么,最好是:

替换

$this->shortenPath($file);
echo ' in ' . $this->path_short . ' on line ' . $line;

$path_short = $this->shortenPath($file);
echo ' in ' . $path_short . ' on line ' . $line;

最后,并在shortenPath()中给出返回值?

我意识到这是几个不同问题的混搭,但我想要了解的是关于声明/使用变量/属性的正确样式的常见问题,特别是在处理方法时。

总结一下:什么时候应该使用$this->foo = $foo

【问题讨论】:

    标签: php parameters this declaration


    【解决方案1】:

    编辑:抱歉,我在下面假设您将创建一个“对象”的新实例,每个错误显然您没有这样做。刚刚编辑了我的答案以反映这一点。

    “我什么时候应该使用 $this->foo = $foo?”

    您可能会在多种情况下这样做,但通常是您在方法中创建 $foo 并希望整个对象都可以访问它。

    例如,如果您想调用一个对象并在该特定对象中使用它(如果扩展没有意义)。你会做这样的事情:

    $foo = new DataModel();
    $this->foo = $foo;
    

    $this->foo = new DataModel();
    

    那个对象可能是一个装饰器或其他与错误处理相关的东西,上面的代码通常会出现在你的构造函数中。然后,您可以随时使用以下方法访问该对象的方法:

    $this->foo->objectMethod();
    

    ..并表达在 cmets 中对此答案的注释:

    “您是否会将 $file 分配给在多个方法中使用的对象?”

    我不会将 $file 分配给对象, 这就是为什么。这个词的语义 “财产”的意思是“属于”。在你的 情况下,您的类是错误处理程序。 $file 不属于错误 handler,属于错误 实例。如果你的课是 MyErrorHandler_Error(为每个 触发错误的实例),然后 $file 将是它的一个属性 类,以及 $line 和 $level。

    从您的其他问题中我能回答的问题:

    1. 两者都不是。我会考虑它的偏好。

    2. 是的 - 如果不是在变量声明中(不确定那里的术语),应该在您的构造函数中设置应该对您的整个对象可用并且对象正常运行所需的任何变量或值,可能应该在您的构造函数中设置排名第一。

    3. 阅读下面的 cmets。因为这个特定的类处理多个错误实例 - 将这些错误的属性分配给对象并不是最佳实践,因为您将用每个新错误覆盖它们。但是,如果您需要访问历史数据,将所有错误和错误属性存储在分配给对象的数组中确实有意义。例如,目前,如果您创建一个新错误 - 这就是您所做的一切。您无法访问此对象创建的任何旧错误。

    4. 见上文

    在将属性分配给对象时,您还应该考虑冲突。您是否可能重新分配,因为如果是这样,旧的财产将消失。相当简单,但您仍然需要考虑。

    【讨论】:

    • 谢谢!不过,我想知道这一点:“如果您需要多个方法中的任何属性,那么建议您将该属性分配给您的对象。如果 printMessage() 是唯一使用这些属性的方法,那么不需要。”以 $file 为例。它从 myErrorHandler() 到 printMessage() 再到 shortPath()。这些都可以在一种方法中,但我将它们分解为可读性/实用性。所以是的,这不仅仅是一种方法,但 $file 只会遍历该链。有一个很长的 Exceptions 方法,我没有在这里包含,并且从不涉及 $file。
    • 我不会将$file 分配给对象,原因如下。 “财产”一词的语义意味着“属于”。在您的情况下,您的类是一个错误处理程序。 $file 不属于错误处理程序,它属于错误实例。如果您的类是 MyErrorHandler_Error(为触发错误的每个实例创建),那么 $file 将是该类的属性,以及 $line$level
    • 实际上构造函数中出现了这一行:set_error_handler(array($this, 'myErrorHandler'));。也就是说,myErrorHandler() 只会在触发错误时由 PHP 本身调用。所以不,这个类的任何部分都不会被手动访问。也许我应该在更简单的地方开始我的 OO PHP 冒险。 :P 所以我同意你的观点:如果这些方法/属性是在类之外/手动访问的,我只需 $this->foo = $foo 一切。但既然这永远不会发生,我想也许我应该坚持使用 $foo/$file/whatever,除非最佳实践另有规定。
    • @netcoder:正是我在上述(迟到的)评论中想要表达的意思。谢谢!
    • @netcoder - 完全同意。如果我查看这个类的预期实现会看到:S
    猜你喜欢
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 2014-10-10
    相关资源
    最近更新 更多