gpt4 book ai didi

php - 关于 PHP 类的一些(高级)问题

转载 作者:可可西里 更新时间:2023-11-01 12:57:09 26 4
gpt4 key购买 nike

我有几个关于 PHP 类的问题,但不能单独提出,所以我开始:

我有一个正在构建的 CMS,它的核心是我的 baseClass、logger、DB 和模块类。 DB 和记录器是静态类,因此我可以在其他对象中使用它们。有很多模块类被加载到 baseClass 中:

class baseClass {
private $_modules;

public function __construct() {
logger::log("instance created.");
$this->_modules = Array()
}

public function __destruct() {
foreach($this->_modules as $name) $this->unloadModule($name);
logger::log("instance destroyed.");
}

public function loadModule($name) {
if (class_exists($name)) {
if (!isset($this->$name)) {
$this->_modules[] = $name;
$this->$name = new $name();
logger::log("module '$name' loaded.");
}
else logger::log("module '$name' already loaded.", 2);
}
else logger::log("module '$name' does not exist.", 3);
}

public function unloadModule($name) {
if (isset($this->$name)) {
unset($this->$name);
foreach($this->_modules as $id => $mod_name) {
if ($name==$mod_name) {
unset($this->_modules[$id]);
logger::log("module '$name' unloaded.");
}
}
}
else logger::log("module '$name' not loaded.", 2);
}

public function listModules() {
return $this->_modules;
}
}
$instance = new baseClass();
$instance->loadModule('moduleX');
$instance->loadModule('moduleY');

问题 1:我的 loadModule 实现是个好主意还是您有更好的解决方案。或者是否有可能以另一种方式扩展一个类,这样我就不必加载模块,而是它们的类定义会将它们自己加载到 baseClass 中,如下所示:

class moduleX reverseExtends baseClass {
public function f1();
public function f2();
}
class moduleY reverseExtends baseClass {
public function f3();
public function f4();
}

$instance = new baseClass();
$instance->f1();
$instance->f2();
$instance->f3();
$instance->f4();

或者至少:

$instance->moduleX->f1();
$instance->moduleX->f2();
$instance->moduleY->f3();
$instance->moduleY->f4();

问题 2: 现在我将我的记录器和数据库类用作静态类(我用 logger::和 DB::调用它们)所以它们可以从任何上下文和范围访问 - 是可以实例化它们并仍然在我的 baseClass 对象中使用它们,但无需在 baseClass 中实例化它们或在每个类中像这样设置它们我将使用它:

public function __construct() {
global $logger_instance;
$this->logger = $logger_instance;
}

我尝试过不同的方法,从传递 baseClass 中原始对象的引用的糟糕方法到使用包装函数的丑陋方法。当 baseClass 未设置并且很难通过模块访问时,使用引用会破坏我的记录器对象 - $this->base->logger->log() - 这反过来需要引用 baseClass 对象($this->base)和在 unloadModule 上杀死我的 baseClass 对象...至于包装函数 - 我希望能够拥有记录器对象的多个实例,因此将实例标识符与函数一起传递会使它变得非常丑陋和“不真实”的解决方案。

我需要这样的东西:

public function someFuncionInsideSomeClass() {
$logger->('Log something'); //or $logger('Log something') with __invoke()
//$logger here is in the global scope
}

问题 3:我希望一个模块能够修改另一个模块的代码。例如,我加载了一个数据库模块,然后我加载了一个记录器模块,并希望将记录器模块集成到数据库模块代码中,而不必弄乱它的原始代码。当然,记录器必须自己处理集成(或者更确切地说,我作为编码器)。简单示例:

class tagCreator {
public function createTag($tag,$data) {
$tag1 = $tag;
$tag2 = '/'.$tag;
return "<$tag1>$data<$tag2>";
}
}
class styleFunctionality {
public function __construct() {
//if class is loaded (tagCreator) | load class (tagCreator)
//do some magic here to tagCreator
//tagCreator -> createTag -> add argument $style
//tagCreator -> createTag -> $tag1 += ' style="'.$style.'"'
//else issue error tagCreator does not exist
}
}
$instance = new baseClass();
$instance->loadModule('tagCreator');

echo $instance->createTag('span','some string');
// returns <span>some string</span>

$instance->loadModule('styleFunctionality');

echo $instance->createTag('span','some string','font-weight: bold');
// returns <span style="font-weight: bold">some string</span>

注意:我不一定是指函数重载,我可能只想更改方法中的一小部分代码

注意 2:调用 $instance->createTag() 不是错误 - 我计划编写一些花哨的 __baseClass 的 call() 函数以从其加载的模块中选择方法

抱歉话题太长了,感谢阅读到这里,我什至希望能回答我的一个问题 :)

最佳答案

对于 DB 和 Logger,我会考虑使用 Singleton 模式。

<?php
class Singleton {
private static $instance;

private function __construct() {
// no-op
}
/**
* Create the instance or return the instance if it has already been created.
*
* @return object
*/

static public function get_instance() {
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
}

?>

一般来说,你可能想看看需要PHP5的PHP框架,比如Kohana。而且,就模式和 PHP 而言,您可能需要查看“PHP 对象、模式和实践”。

关于php - 关于 PHP 类的一些(高级)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5653127/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com