Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重写PHP类实例化_Php_Class_Object - Fatal编程技术网

重写PHP类实例化

重写PHP类实例化,php,class,object,Php,Class,Object,我目前正在从事一个项目,我们正在开发一个应用程序,该应用程序将用于从一组文件/托管环境为多个站点上的内容供电 有许多PHP类的名称,如model\u account和model\u vehicle,它们在名为“另存为类名”的单独文件中定义。我们使用spl\u autoload\u register加载类文件,如下所示(简化): 我们要做的是,如果访问者正在访问站点xxx,我们将创建一个类的实例,例如$account=newmodel_account()-如果文件存在(models/model\u

我目前正在从事一个项目,我们正在开发一个应用程序,该应用程序将用于从一组文件/托管环境为多个站点上的内容供电

有许多PHP类的名称,如
model\u account
model\u vehicle
,它们在名为“另存为类名”的单独文件中定义。我们使用
spl\u autoload\u register
加载类文件,如下所示(简化):

我们要做的是,如果访问者正在访问站点xxx,我们将创建一个类的实例,例如
$account=newmodel_account()
-如果文件存在(
models/model\u xxx\u account.php
),则实际创建类
model\u xxx\u account
的实例,如果不存在,只需包含
models/model\u account.php
文件并创建
model\u account
的实例即可

同样,如果访问者来自站点yyy,如果存在,我们希望使用
model\yyy\u帐户
,如果不存在,则完全返回到
model\u帐户

本质上,我们希望做的是在满足条件的情况下创建另一个类的实例,但是来自同一个实例化调用


我们没有使用像CI或Cake这样的现成框架。此外,我还稍微简化了这篇文章的命名约定。如果我的OO术语不正确,很抱歉。

我想你不能。自动加载程序仅帮助您选择要包含的文件,不允许您更改类

但这不应该是个问题。您只需为每个网站
model\u帐户
命名类即可。站点确定包含哪个文件,从而实例化哪个版本的
model\u account
。因为您永远不会(假设)在一个请求中同时需要
model\u xxx\u账户
model\u yyy\u账户
,所以它们不会相互干扰,即使它们具有相同的名称


PS:我也会给这些文件起相同的名字,并为每个站点创建一个单独的文件夹和一个默认文件夹。这将使每个站点更容易发现被覆盖的文件,并减少名称冲突的风险。

我想你不能。自动加载程序仅帮助您选择要包含的文件,不允许您更改类

但这不应该是个问题。您只需为每个网站
model\u帐户
命名类即可。站点确定包含哪个文件,从而实例化哪个版本的
model\u account
。因为您永远不会(假设)在一个请求中同时需要
model\u xxx\u账户
model\u yyy\u账户
,所以它们不会相互干扰,即使它们具有相同的名称


PS:我也会给这些文件起相同的名字,并为每个站点创建一个单独的文件夹和一个默认文件夹。这将使每个站点更容易发现覆盖的文件,并减少名称冲突的风险。

您肯定可以这样做:

$className = "MyClassName";
$myObject = new $className();

您可以根据您的条件动态定义$className。

您可以这样做:

$className = "MyClassName";
$myObject = new $className();
$SiteID = 'xxx'; // Modify as you wish from your subdomain or whatever
// class_exists triggers the autoloader
if(!class_exists($ClassName =  "model_{$SiteID}_account")){
    // If class is missing, fall back to default
    $ClassName =  "model_account"; // This should exist
}
$Model = new $ClassName(); // Instantiate your Account Model
您可以根据您的条件动态定义$className

$SiteID = 'xxx'; // Modify as you wish from your subdomain or whatever
// class_exists triggers the autoloader
if(!class_exists($ClassName =  "model_{$SiteID}_account")){
    // If class is missing, fall back to default
    $ClassName =  "model_account"; // This should exist
}
$Model = new $ClassName(); // Instantiate your Account Model
只需确保$SiteID包含字母和数字,因此类名友好

而且永远不要从相对路径中要求一次。总是做:

require_once __DIR__.'/models/'.$class_name.'.php'; // PHP 5.3+
// or
require_once dirname(__FILE__).'/models/'.$class_name.'.php'; // PHP 5.2-
为了安全。这样,您就可以确切地知道在哪里寻找Account模型类

只需确保$SiteID包含字母和数字,因此类名友好

而且永远不要从相对路径中要求一次。总是做:

require_once __DIR__.'/models/'.$class_name.'.php'; // PHP 5.3+
// or
require_once dirname(__FILE__).'/models/'.$class_name.'.php'; // PHP 5.2-

为了安全。这样,您就可以确切地知道您在哪里寻找Account模型类。

实际上,听起来您应该使用某种工厂模式来处理类加载

如果您执行了
$account=newsomeclass()
,那么以一个
类Bumblebee
的对象结束是没有任何意义的

从技术上讲,你应该有某种帐户工厂来决定给你哪个类

您的代码最终看起来更像
$account=AccountFactory::retrieveModel()
,这样就可以确定要加载的模型,而无需委托给自动加载程序

自动加载器的要点是本质上说“我想要这个确切的类”,而不是要非常不稳定,或者特别是要做出任何类似的决定。您的工厂实际上可以检查您的文件结构,并确定在函数调用中传回哪个类,在代码中,您不需要依靠
new
来获得所需的模型,因为从理论上看,您的所有帐户模型都将共享相同的接口,或者至少扩展
model\u account


AccountFactory本质上可以说,“
model\u yyy\u account
存在,因此
return new model()

听起来您应该使用某种工厂模式来处理类加载

如果您执行了
$account=newsomeclass()
,那么以一个
类Bumblebee
的对象结束是没有任何意义的

从技术上讲,你应该有某种帐户工厂来决定给你哪个类

您的代码最终看起来更像
$account=AccountFactory::retrieveModel()
,这样就可以确定要加载的模型,而无需委托给自动加载程序

自动加载器的关键是说“我想要这个确切的类“,而不是身体不稳,特别是在做任何类似的决定。您的工厂实际上可以检查您的文件结构,并确定在函数调用中传回哪个类,在代码中,您不需要依靠
new
来获得所需的模型,因为从理论上看,您的所有帐户模型都将共享同一个接口或至少一个