我们可以在php的另一个类中创建一个类的对象吗?

时间:2021-02-24 20:51:56

Can we create an object of a class inside another class in php?I hav made a small application in php,now I am trying to convert the entire code in a class-methods-object fashion.I m now Confused.

我们可以在php的另一个类中创建一个类的对象吗?我在php中做了一个小应用程序,现在我尝试以类方法-对象的方式转换整个代码。我现在困惑。

5 个解决方案

#1


4  

Yes you can, but that increases code coupling and makes testing harder.
I'd suggest creating it outside the class and pass it as an argument (it is called Dependency Injection).

是的,您可以这样做,但是这增加了代码的耦合并使测试更加困难。我建议在类之外创建它,并将它作为参数传递(它称为依赖项注入)。

class Foo
{
}

class Bar
{
  public function __construct(Foo $foo)
  {
    $this->foo = $foo;
  }
}

$foo = new Foo();
$bar = new Bar($foo);

#2


17  

You you can do that, but whether you should depends on the lifetime of the two classes and their relation to each other. Basically, you have the choice between Composition and Aggregation.

您可以这样做,但是您是否应该依赖于两个类的生命周期以及它们之间的关系。基本上,您可以在组合和聚合之间进行选择。

Composition

You use Composition when the created object has a lifetime equal or less than the object that will use it, e.g.

当创建的对象的生存期等于或小于使用它的对象时,您可以使用组合。

class A 
{
    private $belongsToAOnly;

    public function __construct()
    {
        $this->belongsToAOnly = new IBelongToA;
    }
}

In this case A "owns" IBelongToA. When A is destroyed, IBelongToA is destroyed too. It cannot live on it's own and is likely just an implementation detail of A. It could be a ValueObject like Money or some other Data Type.

在这种情况下,A“拥有”IBelongToA。当A被破坏时,IBelongToA也被破坏。它不能独立存在,可能只是a的实现细节,它可以是像Money或其他数据类型的ValueObject。

From Craig Larman's "Applying UML and Patterns":

克雷格·拉曼的《应用UML和模式》:

the composite is responsible for creation and deletion of it's parts - either by itself creating/deleting the parts, or by collaborating with other objects. Related to this constraint is that if the composite is destroyed, its parts must be destroyed, or attached to another composite"

组合负责创建和删除它的部件——通过创建/删除部件,或者通过与其他对象协作。与此约束相关的是,如果复合材料被破坏,它的部件必须被销毁,或者附加到另一个复合材料上。

Aggregation

You use Aggregation when the lifetime of the created object is longer:

当创建对象的生命周期较长时,可以使用聚合:

class A 
{
    private $dbAdapter;

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

Unlike with Composition, there is no implication of ownership here. A uses DbAdapter but when A is destroyed DBAdapter lives on. It's a "uses" relationship instead of an "owns" relationship.

与构图不同,这里没有所有权的含义。一个使用DbAdapter,但当一个被破坏的DbAdapter继续存在。这是一种“使用”关系,而不是“拥有”关系。

Creator Pattern (GRASP)

A good heuristic to decide when an object may create another object at runtime can be found in the Creator Pattern in GRASP which states that objects may create other objects when

可以在Creator模式中找到一种很好的启发式方法,即确定一个对象在运行时何时可以创建另一个对象

  • Instances of B contains or compositely aggregates instances of A
  • B的实例包含或合成了A的实例。
  • Instances of B record instances of A
  • B的实例记录了A的实例
  • Instances of B closely use instances of A
  • B的实例密切使用A的实例
  • Instances of B have the initializing information for instances of A and pass it on creation.
  • B的实例具有A的实例的初始化信息,并在创建时传递它。

Alternatively, you can create Factories whenever you need to create instances of something and aggregate the factory instances, which will give you a cleaner separation of collaborators and creators.

或者,您可以在需要创建实例和聚合工厂实例的时候创建工厂,这将使您更清晰地分离协作者和创建者。

Testability

An issue stemming from creating objects within objects is that they are difficult to test. When you do unit-testing, you usually do not want to recreate and bootstrap the entire system environment but concentrate on testing just that particular class in isolation. To do that, you swap out dependencies of that class with Mock Objects. You cannot do that when you use Composition.

在对象内部创建对象的一个问题是它们很难测试。当您进行单元测试时,您通常不希望重新创建并引导整个系统环境,而是专注于单独测试特定的类。为此,您可以用Mock对象交换该类的依赖项。当你使用合成时,你不能这么做。

So depending on what the collaborators of a class do, you might want to decide to always use Aggregation, because then you are effectively doing Dependency Injection all the way, which will allow you to swap out collaborators of a class easily, for instance to replace them with Mocks.

因此,根据类的协作者做什么,您可能希望始终使用聚合,因为这样您就可以一直有效地执行依赖注入,这将允许您轻松地交换类的协作者,例如用mock替换它们。

#3


4  

yes you can do it ..

是的,你能做到。

here is one example..

这是一个例子。

a.php
<?php
    class a{
        public function function_1(){
           echo "b";
        }
     }
?>


b.php
<?php
     include_once ("a.php");
     class b{
        public function function_b(){
             $a = new a;
             $a->function_1();
        }
      }
      $b= new b;
      $b->function_b();
 ?>

#4


2  

Yes, you can also define a function in a class. You can do everything in a class in php, please post your code where you confused.

是的,您还可以在类中定义函数。你可以在一个php类中做任何事情,请把你的代码贴在你感到困惑的地方。

Examples: Object in a class.

示例:类中的对象。

class Foo
{
   public $bar; // another object!

   public __construct()
   {
      $this->bar = new Bar();
    }
}

(global)Function in a class

(全球)函数在类

<?php
    class Foo
    {
        public function __construct()
        {
            function __construct()
            {
                echo "Yes, I'm a global function!";
            }
        }
    }

    new Foo();
    __construct();

?>

#5


2  

Yes, you can create an object from a specific class from inside another class.

是的,您可以从另一个类内部的特定类创建一个对象。

class SomeClass{

}
class SomeOtherClass {
     function hello(){
         $o = new SomeClass;
     }
}

#1


4  

Yes you can, but that increases code coupling and makes testing harder.
I'd suggest creating it outside the class and pass it as an argument (it is called Dependency Injection).

是的,您可以这样做,但是这增加了代码的耦合并使测试更加困难。我建议在类之外创建它,并将它作为参数传递(它称为依赖项注入)。

class Foo
{
}

class Bar
{
  public function __construct(Foo $foo)
  {
    $this->foo = $foo;
  }
}

$foo = new Foo();
$bar = new Bar($foo);

#2


17  

You you can do that, but whether you should depends on the lifetime of the two classes and their relation to each other. Basically, you have the choice between Composition and Aggregation.

您可以这样做,但是您是否应该依赖于两个类的生命周期以及它们之间的关系。基本上,您可以在组合和聚合之间进行选择。

Composition

You use Composition when the created object has a lifetime equal or less than the object that will use it, e.g.

当创建的对象的生存期等于或小于使用它的对象时,您可以使用组合。

class A 
{
    private $belongsToAOnly;

    public function __construct()
    {
        $this->belongsToAOnly = new IBelongToA;
    }
}

In this case A "owns" IBelongToA. When A is destroyed, IBelongToA is destroyed too. It cannot live on it's own and is likely just an implementation detail of A. It could be a ValueObject like Money or some other Data Type.

在这种情况下,A“拥有”IBelongToA。当A被破坏时,IBelongToA也被破坏。它不能独立存在,可能只是a的实现细节,它可以是像Money或其他数据类型的ValueObject。

From Craig Larman's "Applying UML and Patterns":

克雷格·拉曼的《应用UML和模式》:

the composite is responsible for creation and deletion of it's parts - either by itself creating/deleting the parts, or by collaborating with other objects. Related to this constraint is that if the composite is destroyed, its parts must be destroyed, or attached to another composite"

组合负责创建和删除它的部件——通过创建/删除部件,或者通过与其他对象协作。与此约束相关的是,如果复合材料被破坏,它的部件必须被销毁,或者附加到另一个复合材料上。

Aggregation

You use Aggregation when the lifetime of the created object is longer:

当创建对象的生命周期较长时,可以使用聚合:

class A 
{
    private $dbAdapter;

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

Unlike with Composition, there is no implication of ownership here. A uses DbAdapter but when A is destroyed DBAdapter lives on. It's a "uses" relationship instead of an "owns" relationship.

与构图不同,这里没有所有权的含义。一个使用DbAdapter,但当一个被破坏的DbAdapter继续存在。这是一种“使用”关系,而不是“拥有”关系。

Creator Pattern (GRASP)

A good heuristic to decide when an object may create another object at runtime can be found in the Creator Pattern in GRASP which states that objects may create other objects when

可以在Creator模式中找到一种很好的启发式方法,即确定一个对象在运行时何时可以创建另一个对象

  • Instances of B contains or compositely aggregates instances of A
  • B的实例包含或合成了A的实例。
  • Instances of B record instances of A
  • B的实例记录了A的实例
  • Instances of B closely use instances of A
  • B的实例密切使用A的实例
  • Instances of B have the initializing information for instances of A and pass it on creation.
  • B的实例具有A的实例的初始化信息,并在创建时传递它。

Alternatively, you can create Factories whenever you need to create instances of something and aggregate the factory instances, which will give you a cleaner separation of collaborators and creators.

或者,您可以在需要创建实例和聚合工厂实例的时候创建工厂,这将使您更清晰地分离协作者和创建者。

Testability

An issue stemming from creating objects within objects is that they are difficult to test. When you do unit-testing, you usually do not want to recreate and bootstrap the entire system environment but concentrate on testing just that particular class in isolation. To do that, you swap out dependencies of that class with Mock Objects. You cannot do that when you use Composition.

在对象内部创建对象的一个问题是它们很难测试。当您进行单元测试时,您通常不希望重新创建并引导整个系统环境,而是专注于单独测试特定的类。为此,您可以用Mock对象交换该类的依赖项。当你使用合成时,你不能这么做。

So depending on what the collaborators of a class do, you might want to decide to always use Aggregation, because then you are effectively doing Dependency Injection all the way, which will allow you to swap out collaborators of a class easily, for instance to replace them with Mocks.

因此,根据类的协作者做什么,您可能希望始终使用聚合,因为这样您就可以一直有效地执行依赖注入,这将允许您轻松地交换类的协作者,例如用mock替换它们。

#3


4  

yes you can do it ..

是的,你能做到。

here is one example..

这是一个例子。

a.php
<?php
    class a{
        public function function_1(){
           echo "b";
        }
     }
?>


b.php
<?php
     include_once ("a.php");
     class b{
        public function function_b(){
             $a = new a;
             $a->function_1();
        }
      }
      $b= new b;
      $b->function_b();
 ?>

#4


2  

Yes, you can also define a function in a class. You can do everything in a class in php, please post your code where you confused.

是的,您还可以在类中定义函数。你可以在一个php类中做任何事情,请把你的代码贴在你感到困惑的地方。

Examples: Object in a class.

示例:类中的对象。

class Foo
{
   public $bar; // another object!

   public __construct()
   {
      $this->bar = new Bar();
    }
}

(global)Function in a class

(全球)函数在类

<?php
    class Foo
    {
        public function __construct()
        {
            function __construct()
            {
                echo "Yes, I'm a global function!";
            }
        }
    }

    new Foo();
    __construct();

?>

#5


2  

Yes, you can create an object from a specific class from inside another class.

是的,您可以从另一个类内部的特定类创建一个对象。

class SomeClass{

}
class SomeOtherClass {
     function hello(){
         $o = new SomeClass;
     }
}