PHP - 从另一个类调用类函数

时间:2015-04-28 22:33:26

标签: php function class oop

我正在尝试创建一个可以从其他类调用的错误处理类,但是当我从另一个类调用错误处理类中的函数时,我收到以下错误:

  

致命错误:在第361行(filepath_here)中调用null成员函数fetch_error_text()

这是我到目前为止的代码:

int

感谢。

7 个答案:

答案 0 :(得分:1)

我不建议使用全局...但是这应该修复它... global需要在每个使用它的函数中。您的global似乎还需要$return_msg

global $errhandle_func_call;    
class ERR_HANDLE
{
   public function __construct()
   {
   }

   public function fetch_error_text($err_text)
   {
       global $return_msg;
       $err_text_display = $return_msg[$err_text];
       return "<h4>" . $err_text_display . "</h4>";
   }
}

$errhandle_func_call = new ERR_HANDLE();

class BASKET
{
    public function view_basket()
    {
        global $errhandle_func_call;
        //some_code_here
        if($query->num_rows < 1)
        {
            echo $errhandle_func_call->fetch_error_text("basket_empty");
        }
    }
}

[更新2015-04-29] 仅仅是为了它,快速,粗略,介绍我的建议......从最简单到最难......我也是要改变你的套管,因为ALL_UPPERCASE通常用于表示常数,而我是OCD。

静态错误类:

class ErrorType {
    const UserError     = 1;
    const NotFoundError = 2;

    public static function getMessage( $messageId ) {
        switch( $messageId ) {
            case self::UserError: return "user error";
            case self::NotFoundError: return "not found error";
        }
    }
}
class ErrorHandler {
    public static function fetchErrorText( $errorType) {
        return "<h4>".ErrorType::getMessage($errorType)."</h4>";
    }
}

ErrorHandler::fetchErrorText( ErrorType::UserError );

这绝对是最简单的,让你远离全局。我添加了ErrorType类来减少&#34;魔术字符串&#34;在代码中为您提供常量值以传递给函数。这将有助于避免拼写错误等,因为您的IDE可以为您提供智能感知。

但是,静态类对单元测试不友好。那么,那就是&#34;依赖倒置&#34;可以发挥作用。反转依赖关系的最简单方法是服务定位器,因为您不必修改构造函数以便能够传入对象的实例。有些人认为这是一种反模式,但它在正确的情况下非常有用(例如,约定配置等)。

依赖性反转:服务定位器

//first thing you need for inversion is an interface
interface IHandleError {
    public function getErrorMessage( $errorType );
}

//imaginary ServiceLocator class, defining instance of interface to use
ServiceLocator::define( array(
    'IHandleError' => 'SomeNamespace\ErrorHandler'
) );

class Basket {
    public function viewBasket() {
        //grab it when you need it
        $errorHandler = ServiceLocator::get('IHandleError');
        if( query->num_rows < 1 ) {
            echo $errorHandler->getErrorMessage( ErrorType::BasketEmpty );
        }
    }
}

ServiceLocator对象是虚构的......但最简单的形式是它只是一个key =&gt;的数组。 value,其中值指向类...而:: get()方法实例化类的实例或单例。我做了更多&#34;魔术弦&#34;在这里,但并不想让它太复杂。

依赖性反转:依赖注入

另一方面,依赖注入在概念上比ServiceLocator更简单...但有时在实现中更难,因为您需要访问来修改类的构造函数并能够修改其实例以传入对象。

class Basket {
    private $_errorHandler;
    public function __construct( IHandleError $errorHandler ) {
        $this->_errorHandler = $errorHandler;
    }
}

$basket = new Basket( $errorHandler );

这3个中的任何一个都会引导你远离全局变量并提高代码的可维护性。

答案 1 :(得分:1)

为什么不使用遗产? 您的类BASKET可以从ERR_HANDLE扩展:

class BASKET  extends ERR_HANDLE { 
      public function view_basket() {
          //some_code_here 
          if($query->num_rows < 1) { 
                  echo parent::fetch_error_text("basket_empty"); 
          } 
      }  
   }

答案 2 :(得分:1)

依赖注入(DI)很容易

根据天气情况,您的课程需要依赖关系,或者可选取决于您如何“注入”它。请注意,“依赖”可以是对象(实例化类)或property(类成员变量)。

看起来,你的“BASKET”类需要“ERR_HANDLE”类才能正常工作,因此使用“构造函数注入”是“最佳实践”。构造函数注入意味着“将它”注入“类”的“构造”方法中。

这种(依赖注入)允许在许多其他事物之间分离关注点。

ErrorHandle.php

<?php

class ERR_HANDLE
{
    public function fetch_error_text($err_text)
    {
        $err_text_display = $return_msg[$err_text];
        return "<h4>" . $err_text_display . "</h4>";
    }
}

Basket.php

<?php

class BASKET
{
    private $err_handle;

    public function __construct($err_handle)
    {
        $this->err_handle = $err_handle;
    }

    public function view_basket()
    {
        //some_code_here

        if($query->num_rows < 1)
        {
            // The next line is where you use the injected objects method.
            return $this->err_handle->fetch_error_text("basket_empty");
        }
    }
}

然后是实际注射

<?php

// Instantiate the error handle class.
$err_handle = new ERR_HANDLE();

// Whilst instantiating the BASKET class, inject the ERR_HANDLE object.
$basket = new Basket($err_handle);

// View the basket.
echo $basket->view_basket();

现在,您应该能够解决的最后一个问题是如何将变量'$ return_msg'添加到'ERR_HANDLE'类中。 PS:注射它。

我建议阅读namespaces,熟悉classes and objects并阅读有关依赖注入的内容。

永远不要停止学习......

答案 3 :(得分:0)

看起来您实际上是在尝试运行其成员函数的范围内实例化ERR_HANDLE的实例。

$ errhandle_func_call是在BASKET类范围之外创建的,但该对象需要在BASKET类的公共函数中可​​用

答案 4 :(得分:0)

您可以使用自动加载文件加载所有&#34; .class.php&#34;使用此代码在目录中创建文件。

item(3)

因此您将所有类文件放在该文件所在的目录中。 并且您只需将此文件包含在您要使用任何类

的所有页面中

答案 5 :(得分:0)

你可以用另一种方式做到这一点。

<?php

class error {

    public function hes_dead() {
        // deal with error
    }

}

class needs_error_class {

    private $err;
    public function __construct() {

        // This is called dependency injection.
        $this->err = new Error;

    }

    public function some_function() {

        // need that error handing now
        $this->err->hes_dead();
    }
}

答案 6 :(得分:0)

您也可以尝试这种方式来打电话给您的班级。

class ERR_HANDLE
{
   public function empty_basket_error_text($err_text)
   {
       return "<h4>".$err_text."</h4>";
   }
}
class BASKET
{
    public function view_basket()
    {
        //some_code_here
        //if($query->num_rows < 1)
        // {
            $this->errhandle = new ERR_HANDLE();
            return $this->errhandle->empty_basket_error_text("Empty basket");
        // }
    }
}
$basket = new BASKET();
echo $basket->view_basket();

http://3v4l.org/U2fsH