php:在可选文件中多次有效地运行具有一次性加载类的函数
阅读回复后我重写了我的问题。
假设我有一个理论上的 php 应用程序,它使用执行不同操作的对象。 对于应用程序加载的每个页面,将运行不同的脚本。
现在我制作了一个简单的 php 脚本来创建一个简单的对象。 (这都是编出来的,我只是想在编码之前理解这一点)
$user = new userClass($db);
$user->login($credentials);
一切都很好,我什至可以在创建用户类后重复该过程几次
$user = new userClass($db);
$user->login($credentials);
...
$user->login($credentials2);
现在想象一下如果这两个部分被分成2个不同的php文件。
file1:
$user = new userClass($db);
$user->login($credentials);
file2:
$user->login($credentials2);
include file1
include file2
如果它们按顺序运行一切都很好,但如果不是,或者根本不包含 file1...
file2:
$user->login($credentials);
file1:
$user = new userClass($db);
$user->login($credentials2);
include file2
include file1
那么它将无法工作...它们必须维持顺序,所以让我们创建一个主 php 文件无论如何都会被加载。
main file:
$user = new userClass($db);
file1:
$user->login($credentials);
file2:
$user->login($credentials2);
(例如包含自动加载的文件) 包括主要 包含文件1 包含文件2 或者 包括主要 包含文件2 包含文件1 或者 包括主要 include file2
现在 file1 和 2 可以按任意顺序加载,并且一个不依赖另一个,但是如果 file1 或 file2 都不需要怎么办?
main file:
$user = new userClass($db);
//nothing else gets loaded
那么主文件也是不必要的,并且将被证明是一个资源消耗者,当然,如果它是一个类,那没有问题,但是如果主文件加载了数百个从未使用过的类怎么办?
一点也不优雅。
然后让我们尝试用另一种方式来做,让我们完全废弃主文件并像这样做(下面是我想要实现的简单示例):
file1:
if(!is_object($user)){
$user = new userClass($db);
}
$user->login($credentials);
file2:
if(!is_object($user)){
$user = new userClass($db);
}
$user->login($credentials2);
当然,它可以工作,但它并不优雅,现在是吗?
让我们尝试使用方法重载...
class loader {
private $objects;
private $db;
function __construct($db){
$this->objects = array();
$this->db = $db;
}
function __get($name){
if(!isset($this->objects[$name])){
return $this->objects[$name] = new $name($this->db);
}
}
}
main file:
$loader = new loader($db);
file1:
$loader->user->login($credentials);
file3:
$loader->user->login($credentials3);
file2:
$loader->user->login($credentials2);
file4:
$loader->user->login($credentials4);
似乎可行,直到您意识到您不能再为以这种方式创建的任何对象提供除 $db 之外的任何其他变量。 这意味着加载器类仅限于仅与用户类一起使用(例如) 因为将加载器类与任何其他类一起使用将需要编辑加载器类
和一个简单的脚本,如下所示:
$user = new userClass($this->db);
$user->login($credentials);
$form = new formClass($_POST);
$form->process($info);
将需要 2 个单独的加载器类或加载器类中至少有 2 个方法,
class loader {
private $objects;
private $db;
function __construct($db){
$this->objects = array();
$this->db = $db;
}
function getuserclass($name){
if(!isset($this->objects[$name])){
return $this->objects[$name] = new $name($this->db);
}
}
function getformclass($name){
if(!isset($this->objects[$name])){
return $this->objects[$name] = new $name($_POST);//just an unrealistic example.
}
}
}
main file:
$loader = new loader($db);
file1:
$loader->getuserclass('user')->login($credentials);
file3:
$loader->getformclass('form')->process($info);
但这也不优雅。
这真正应该如何完成?
after reading the responses I have rewritten my question.
Let's say I have a theoretical php application that uses objects that do different things.
For every page that gets loaded by the application, different scripts will be run.
now I made a simple php script that creates a simple object.
(this is all made up, I'm just trying to understand this before I code it)
$user = new userClass($db);
$user->login($credentials);
all is fine, and I can even repeat the procedure several times after creating the user class
$user = new userClass($db);
$user->login($credentials);
...
$user->login($credentials2);
now imagine if these 2 parts are split in 2 different php files.
file1:
$user = new userClass($db);
$user->login($credentials);
file2:
$user->login($credentials2);
include file1
include file2
if they are run in order all is fine, but if they are not, or if file1 is not included at all...
file2:
$user->login($credentials);
file1:
$user = new userClass($db);
$user->login($credentials2);
include file2
include file1
then it won't work... they have to maintain order, so lets make a main php file that gets loaded no matter what.
main file:
$user = new userClass($db);
file1:
$user->login($credentials);
file2:
$user->login($credentials2);
(included files with autoloading for example)
include main
include file1
include file2
or
include main
include file2
include file1
or
include main
include file2
now file1 and 2 can be loaded in any order, and one does not depend on the other, but what if both file1 or file2 are unnecessary?
main file:
$user = new userClass($db);
//nothing else gets loaded
then the main file is also unnecessary, and will prove to be a resource hog, sure if its one class it's no problem, but what if the main file loads hundreds of classes that never get used?
not elegant at all.
Then let's try to do it another way, let's scrap the main file completely and do it like this (below is the bare bone example of what I want to achieve):
file1:
if(!is_object($user)){
$user = new userClass($db);
}
$user->login($credentials);
file2:
if(!is_object($user)){
$user = new userClass($db);
}
$user->login($credentials2);
sure, it works, but it's not elegant, now is it?
let's try it with method overloading...
class loader {
private $objects;
private $db;
function __construct($db){
$this->objects = array();
$this->db = $db;
}
function __get($name){
if(!isset($this->objects[$name])){
return $this->objects[$name] = new $name($this->db);
}
}
}
main file:
$loader = new loader($db);
file1:
$loader->user->login($credentials);
file3:
$loader->user->login($credentials3);
file2:
$loader->user->login($credentials2);
file4:
$loader->user->login($credentials4);
seems to work, until you realize that you can no longer give any of the objects that are created this way any other variable except $db.
This means that loader class is limited to use with user class only (for example)
because using loader class with any other class will require editing of the loader class
and a simple script like this:
$user = new userClass($this->db);
$user->login($credentials);
$form = new formClass($_POST);
$form->process($info);
will require 2 separate loader classes or at least 2 methods in the loader class
class loader {
private $objects;
private $db;
function __construct($db){
$this->objects = array();
$this->db = $db;
}
function getuserclass($name){
if(!isset($this->objects[$name])){
return $this->objects[$name] = new $name($this->db);
}
}
function getformclass($name){
if(!isset($this->objects[$name])){
return $this->objects[$name] = new $name($_POST);//just an unrealistic example.
}
}
}
main file:
$loader = new loader($db);
file1:
$loader->getuserclass('user')->login($credentials);
file3:
$loader->getformclass('form')->process($info);
but this is not elegant either.
How is this really supposed to be done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这可能对您有用:
如果您想要多个实例,您可能可以在每次调用加载器时包含一个额外的第一个参数(即名称),并更改加载器代码以使用第一个参数作为对象的键,然后传递剩下的交给对象的构造函数。
This would probably work for you:
If you want multiple instances you could perhaps include an additional first argument in each call to loader that is a name, and change the loader code to use the first arg as a key for the object, and pass the rest to the object's constructor.
在我看来,这正是为什么通过应用程序使用 include() 是一个坏主意的原因,并且可能会造成严重的维护麻烦。特别是对于不熟悉代码的人。他们可能会在两年后打开一个 PHP 文件并看到一个变量......并且不知道它是什么或它在哪里初始化。
如果您遇到此类问题,您的应用程序的基本结构可能需要重做。组织应用程序的更好方法是将所有包含内容放在应用程序的顶部,这样就不会不清楚包含哪些文件或包含它们的顺序。然后使用模板系统来控制输出。不要使用“includes()”内联插入代码。使用它们更像是 C 包含。您包含的文件应该包含函数和类,以及在全局范围内运行的很少(如果有的话)代码。
这样做,我想您会发现您将不再遇到此类问题。
imo, this is exactly why using include() through an app is a bad idea, and can create serious maintenance headaches. Especially for people who are unfamiliar with the code. They may open a PHP file two years from now and see a variable... and have no idea what it is or where it is initialized.
If you are encountering this sort of problem, your app's basic structure probably needs to be redone. a better way to organize your app is to put all includes at the top of your app, so that there's no ambiguity about what files are included, or the order that they are included. And then use a templating system to control output. Dont use 'includes()' to insert code inline. Use them instead more like C includes. Your included files should house functions and classes, and very little, if any code, that runs in the global scope.
Do that, and I think you'd find that you'll stop encountering these sort of problems.
只需使用自动加载器和单例模式:
创建一个类,将所有类(例如 /modules/ )与所包含的类具有相同的文件名,仅记住声明。
现在将此代码(在“主文件”上)包含在所有页面的顶部:
您可能想要创建一个单例类(它是一个对象模式,它基本上确保该类仅存在 1 个实体)
文件:UserClass.php
现在要使用它,您可以简单地这样做:
simply use the autoloader and singleton pattern:
create a class where you put all your classes(for example /modules/ )with the same filename as the contained class,remember ONLY the declaration.
now include this code(on a "main file")on top of all your pages:
you may want to create a singleton class(it's a object pattern,it basically ensure that only 1 entity of the class exists)
file:UserClass.php
now to use it you can simply do like so: