php帮助正确定义类并在不同构造函数上调用


php Help Right Way to Define Classes and Called on different Constructor

学习正确的方法:创建一个类,"构造函数"调用所有类并将其扩展到应用程序。我有一个文件来定义php类型的所有类文件:

<?php
    $APP_PHPCORE_DIR=$_SERVER['DOCUMENT_ROOT'] . '/control/class';
    if (!defined('ERRORMANAGER_CLASS'))         define('ERRORMANAGER_CLASS'         ,'class.managererror.php'           );  
    if (!defined('DBMANAGER_CLASS'))            define('DBMANAGER_CLASS'            ,'class.managerdb.php'              );
    if (!defined('USERMANAGER_CLASS'))          define('USERMANAGER_CLASS'          ,'class.manageruser.php'            );  #Clase sobre Administracion de Usuario
    if (!defined('CRIPMANAGER_CLASS'))          define('CRIPMANAGER_CLASS'          ,'class.managercrip.php'            );
    require_once $APP_PHPCORE_DIR . '/' . ERRORMANAGER_CLASS;
    require_once $APP_PHPCORE_DIR . '/' . DBMANAGER_CLASS;
    require_once $APP_PHPCORE_DIR . '/' . USERMANAGER_CLASS;
    require_once $APP_PHPCORE_DIR . '/' . CRIPMANAGER_CLASS;
?>

然后在有了这个文件后,我在index.php 中调用它

<?php
require_once('config/classlib.php');
?>

稍后,逐步处理每个文件,创建我将使用的类,并设计类库,这些类有一个构造函数,我必须在其中调用"config/classlib.php"中定义的每个类具体如下:示例1

<?php #first File
class Class_Main{
    function __construct(){
        # Contructior de la clase (No usado).
        $this   ->  ERRORMANAGER            =   new Class_ErrorManager();
        $this   ->  DBMANAGER               =   new Class_BDManager();
        $this   ->  USERMANAGER             =   new Class_UserManager();
        $this   ->  CRIPMANAGER             =   new Class_CripManager();
    }
    #bulk of functions...
}
?>

示例2

<?php #second File
class Class_ErrorManager{
    function __construct(){
        # Contructior de la clase (No usado).
        $this   ->  DBMANAGER               =   new Class_BDManager();
        $this   ->  USERMANAGER             =   new Class_UserManager();
        $this   ->  CRIPMANAGER             =   new Class_CripManager();
    }
    #bulk of functions...
}
?>

示例3

<?php
class Class_UserManager{
    function __construct(){
        # Contructior de la clase (No usado).
        $this   ->  ERRORMANAGER            =   new Class_ErrorManager();
        $this   ->  DBMANAGER               =   new Class_BDManager();
        $this   ->  CRIPMANAGER             =   new Class_CripManager();
    }
    #bulk of functions...
}
?>

我认为我走在了正确的轨道上,但我不确定这是否100%正确,因为我遇到了错误:

"Fatal error: Allowed memory size of 134217728bytes exhausted (tried to allocate 33554432 bytes)"

这是通过在类的构造函数中添加一行来实现的。

$this   ->  USERMANAGER             =   new Class_UserManager();

有些人对如何避免这种情况有更好的想法,这只是一个例子,但事实是他们有超过16个不同的类。调用构造函数让我花了很多钱

PS:在构造函数中,我确保不要调用类本身

现在的代码有几个问题。内存不足,因为在Class_UserManagerClass_ErrorManager类之间有相互递归而没有递归终止。

如果您跟踪程序的执行,您会注意到当您实例化Class_UserManager类时,将执行以下步骤:

  • Class_ErrorManager实例化

    1. Class_BDManager被实例化
    2. Class_UserManager实例化

      • Class_ErrorManager实例化

        1. Class_BDManager被实例化
        2. Class_UserManager被实例化

        对象的创建一直持续到内存耗尽。

您可以通过使用依赖注入来解决这些问题,也就是说,不必在类的构造函数中实例化类,只需将它们作为参数即可。默认情况下,对象是通过引用传递的,因此可以显著减少内存占用。

<?php
class Class_ErrorManager
{
     public function __construct(Class_BDManager $bdManager, Class_UserManager $usermanager, Class_CripManager $cripManager)
     {
          $this->DBMANAGER = $bdManager;
          // etc...
     }
}

此外,您还应该查看PHP编码样式指南(PSR-2)

您的代码已修改:http://pastebin.com/aSSvmA8N

  • 它创建了一个包含所有引用的标准对象
  • 所有类都会先安装
  • 所有实例都使用循环中的实例包进行初始化

其目的是将初始化与构造分离。因此,您可以首先构造所有实例,然后使用引用的hole包初始化它们。为了防止多余的代码,有一个带有init()方法的基类。

注意:在每个实例中保存所有引用不是常见的。但由于这是指导方针,所以这是一个简单的解决方案


一个更好设计的的工作演示库结构

<?php
class Application
{
  protected
    $_error_manager = null,
    $_db_manager    = null,
    $_crip_manager  = null
  ;
  public function __construct()
  {
    $this->_error_manager = new Error_Manager($this, 'some inititialization data');
    $this->_db_manager    = new Db_Manager   ($this, 'some inititialization data');
    // ...
    $this->_error_manager->log('Application initialized.');
  }
  public function get_error_manager()
  {
    return $this->_error_manager;
  }
}
class Base_Class
{
  protected $_application = null;
  public function __construct(Application $application)
  {
    $this->_application = $application;
  }
}
class Error_Manager extends Base_Class
{
  public function __construct(Application $application, $other_argument)
  {
    parent::__construct($application);
    // ...
    $this->log('Error manager initialized.');
  }
  public function log($str)
  {
    echo "$str<br>'n";
  }
}
class Db_Manager extends Base_Class
{
  function __construct(Application $application, $other_argument)
  {
    parent::__construct($application);
    // ...
    $this->_application->get_error_manager()->log('Database manager initialized.');
  }
}
new Application();
?>

或者做一件肮脏的事,并提供一系列参考:

<?php
class Base_Class
{
  protected
    $_application    = null,
    $_error_manager = null,
    $_db_manager    = null,
    $_crip_manager  = null,
    $_another_class = null
  ;
  public function __construct()
  {
  }
  public function init($instances)
  {
    $this->_application     = $instances->application;
    $this->_error_manager   = $instances->error_manager;
    $this->_db_manager      = $instances->db_manager;
    $this->_crip_manager    = $instances->crip_manager;
    $this->_another_class   = $instances->another_class;
    $this->_error_manager->log(get_class($this) . " initialized.");
  }
}
class Application extends Base_Class
{
  public function __construct()
  {
    $instances = new stdClass();
    $instances->application   = $this;
    $instances->error_manager = new Error_Manager();
    $instances->db_manager    = new Db_Manager();
    $instances->crip_manager  = new Crip_Manager();
    $instances->another_class = new Another_Class();
    $this->init($instances);
    // after initialized itself we can do:
    $this->_error_manager->init($instances);
    $this->_db_manager   ->init($instances);
    $this->_crip_manager ->init($instances);
    $this->_another_class->init($instances);
  }
}
class Error_Manager extends Base_Class
{
  public function __construct()
  {
  }
  public function log($str)
  {
    echo "$str<br>'n";
  }
}
class Db_Manager extends Base_Class
{
  function __construct()
  {
    parent::__construct();
  }
}
class Crip_Manager extends Base_Class
{
  function __construct()
  {
    parent::__construct();
  }
}
class Another_Class extends Base_Class
{
  function __construct()
  {
    parent::__construct();
  }
}
new Application();
?>