我可以在PHP类中包含代码吗?

我可以在PHP类中包含代码吗?,php,oop,class,Php,Oop,Class,我想创建一个PHP类,比如Myclass.PHP。现在在这个类中,我只想定义类本身和一些实例变量。但是所有方法都必须来自Myclass_methods.php文件。我可以把那个文件包含到类主体中吗 我有很好的理由把这个分开。简言之,我将有一个后端,可以在其中更改类的业务逻辑,而所有其他内容必须保持不变。系统为我维护所有的ORM和其他东西 但是,如果这是一个坏主意,那么在编辑业务逻辑之后重新生成整个类文件(因此,在本例中是用户定义的方法)可能会更好 性能问题:如果在一个请求中只包含一次Myclas

我想创建一个PHP类,比如Myclass.PHP。现在在这个类中,我只想定义类本身和一些实例变量。但是所有方法都必须来自Myclass_methods.php文件。我可以把那个文件包含到类主体中吗

我有很好的理由把这个分开。简言之,我将有一个后端,可以在其中更改类的业务逻辑,而所有其他内容必须保持不变。系统为我维护所有的ORM和其他东西

但是,如果这是一个坏主意,那么在编辑业务逻辑之后重新生成整个类文件(因此,在本例中是用户定义的方法)可能会更好


性能问题:如果在一个请求中只包含一次Myclass.php,那么实际上Myclass_methods.php也应该只包含一次。可能是错的。专家?

创建具有相关基本功能的核心类,然后使用所需的方法进行扩展,这似乎是一种更符合逻辑的方法。

否。不能在类主体中包含文件。
在定义类的文件中,只能包含方法主体中的文件或类主体之外的

根据你的描述,我认为你想要这个:

<?php // MyClass.php
class MyClass
{
    protected $_prop;
    include 'myclass-methods.php';
}

<?php // myclass-methods.php
public function myMethod()
{
   $this->$_prop = 1;
}
但这是可能的

<?php // MyClass.php
class MyClass
{
    protected $_prop;
    public function __construct() // or any other method
    {
        include 'some-functions.php';
        foo($b); // echoes 'a';
    }
}

<?php // some-functions.php
$b = 'a';
function foo($str)
{
   echo $str;
}

我首先要说,我不太清楚为什么这个问题不能最好地使用包含方法的基类、包含数据的子类和动态类加载来解决。我想你有充分的理由

一旦您的提供者支持PHP5.4,您就可以使用traits做您想做的事情

代码文件:

if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');

class Pet {
  use PetSounds;
}

$myPet = new Pet();
$myPet->speak();
if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');

class Pet {
  public function __call($name, array $arguments)
  {
    array_unshift($arguments, $this);
    return call_user_func_array("TraitFunc_$name", $arguments);
  }
}

$myPet = new Pet();
$myPet->speak();
文件cat.php

trait PetSounds {
  function speak() { echo 'meow'; }
}
function TraitFunc_speak(Pet $that) { echo 'meow'; }
文件dog.php

trait PetSounds {
  function speak() { echo 'woof'; }
}
function TraitFunc_speak(Pet $that) { echo 'woof'; }
通过将两个包含文件命名为相同的文件,将它们放在不同的子目录中,并使用set_include_path()或定义一个u autoload()函数在它们之间进行选择,可以使这一点更加清晰。正如我所说,使用继承可以更好地解决同样的问题。但是,如果您有多重继承类型问题,例如,如果您有四种宠物,五种颜色,三种头发类型,并且您需要为60个不同的类中的每一个使用不同的方法组合,那么这就是正确的解决方案

5.4目前只是一个候选版本(截至2012年2月24日),即使发布了,大多数主机也不会支持它好几个月——我的5.3发布后18个月才支持它。在此之前,您必须编写完全独立且完整的类文件。不过,您可以在设置类的格式时考虑到特性的最终变化

现在,你可以使用神奇的方法部分地得到你想要的,并且在traits可用时可以轻松地升级到traits

代码文件:

if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');

class Pet {
  use PetSounds;
}

$myPet = new Pet();
$myPet->speak();
if ($pet === 'dog') include 'dog.php';
elseif ($pet === 'cat') include 'cat.php';
else die('Unknown pet');

class Pet {
  public function __call($name, array $arguments)
  {
    array_unshift($arguments, $this);
    return call_user_func_array("TraitFunc_$name", $arguments);
  }
}

$myPet = new Pet();
$myPet->speak();
文件cat.php

trait PetSounds {
  function speak() { echo 'meow'; }
}
function TraitFunc_speak(Pet $that) { echo 'meow'; }
文件dog.php

trait PetSounds {
  function speak() { echo 'woof'; }
}
function TraitFunc_speak(Pet $that) { echo 'woof'; }

但是,您受到限制,因为您的函数无法访问私有和受保护的类属性和方法,并且您不能使用此方法提供神奇的方法,例如_get()。Traits将解决这两个限制。

由于PHP5.4版本,您可以创建动态对象,如下所示:


但是这几乎不是最好的做法。

用特质做这个怎么样?这是一个可以接受的选择吗?这是我目前正在试验的东西,它似乎在相当长的一段时间内起作用

我正在做的事情的简化版本基本上是这样的。我有一个共享核心文件和多个项目的应用程序。在这些项目中,我有一些模块。我希望在核心级别上具有可用于整个项目的功能,但仅限于该特定项目

我的项目总监

if(is_file(PROJECT_PATH.'/project_extensions.trait.php')){
  // additional functions for this specific project
  require_once(PROJECT_PATH.'/project_extensions.trait.php');
}else{
  // no additional functions
  trait Extensions{};
}


Class Project{
  USE Extensions;

  // default functions shared between all projects
  function shared_stuff(){

  }
}
扩展名文件

trait Extensions{
  // project-specific extensions
  function this_project_only(){
    echo 'Project Only';
  }
}
项目中的模块文件

class MyModule extends Modules{ // modules extends projects in a different class not relevant here

  function do_something(){
    echo $this->project_only();
  }
}

重新提出一个老问题,但这是一个相当简单的解决方案。您是否需要通用函数调用对您的类是独占的?如果没有,只需将公共函数文件包含在与类相同的范围内即可。您需要在类中创建方法,但它们只需要调用公共函数。下面是一个简单的SOAP服务器示例:

<?php

include 'post_function.php';

$server = new SoapServer( null, array('uri' => "http://localhost/") );
$server->setClass(  'postsoapclass' );
$server->handle();


class postsoapclass
{
    public function animalNoise( $animal )
    {
        return get_animal_noise($animal);
    }
}

?>

post_function.php

<?php

function get_animal_noise($animal)
{
    if(strtolower(trim($animal)) == 'pig')
    {
        return 'Oink';
    }
    else 
    {
        return 'This animal is mute';
    }
}

?>

在我维护同一软件的免费版本和高级版本的情况下,我必须按照您所描述的那样做。因为,正如@Gordon所指出的,你不能完全做到这一点:

class SomeClass {  

  premium_file = "premium.php";
  if (file_exists($premium_file)) {
    require($premium_file);
  }
相反,我这样做:

  premium_file = "premium.php";
  if (file_exists($premium_file)) {
    require($premium_file);
  }

  class SomeClass {
    ...
对于要引用的函数,在主类中创建类方法,并调用包含的文件的方法,将
$this
指针作为参数传递。为了一眼就能看出函数的位置,我将为包含的函数添加前缀,如下所示:

  class SomeClass {
    ... 
    // Premium functions
    public function showlist() {
      premium_showlist($this);
    }

我最近遇到了这个问题,并提出了一个解决方案,这对我的情况很有帮助。我希望在一个类中包含许多函数,但该类变得臃肿,因此希望将类函数分成多个组以提高可读性。这花了一点时间来完成,但是由于类的函数不太依赖于$this,我从类函数中删除了“$this”,并创建了几个助手文件来包含这些函数。当$this是必需的时,我仍然可以将该函数移动到助手文件中,方法是将$this传递给该函数,并在必要时添加公共set/get函数。这是一个黑客,但它肯定会帮助别人

` 类myClass { var x

    function myClass()
    {
        $this->x = 0;
    }

    function myFunc1Group1()
    {
        $x = $this->x;
        $x++;
        $this->x = $x;
    }
    function myFunc2Group1(){}

    function myFunc1Group2(){}
    function myFunc2Group2(){}
}
    function myClass()
    {
        $this->x = 0;
    }

    function doSomething()
    {
        // not called on $this but takes $this as a parameter
        myFunc1Group1($this);
    }
}
`

可以工作到

` 类myClass { var x

    function myClass()
    {
        $this->x = 0;
    }

    function myFunc1Group1()
    {
        $x = $this->x;
        $x++;
        $this->x = $x;
    }
    function myFunc2Group1(){}

    function myFunc1Group2(){}
    function myFunc2Group2(){}
}
    function myClass()
    {
        $this->x = 0;
    }

    function doSomething()
    {
        // not called on $this but takes $this as a parameter
        myFunc1Group1($this);
    }
}
`

和辅助函数集1


函数myFunc1Group1($THIS\u对象)
{
$x=$THIS_OBJECT->getX();
$x++;
$THIS_OBJECT->setX($x);
}
函数myFunc2Group1($THIS_OBJECT){}

和辅助函数集2等

可能不是所有情况下最好的方法,但对我帮助很大。基本上,类函数只用于构造和委托,而计算