编写我自己的 PHP 框架,需要一些关于方法的意见/建议

发布于 2024-10-14 10:15:09 字数 1553 浏览 2 评论 0原文

在开始之前,该框架无意与 Zend、Symfony、Cake 或任何其他框架竞争。它主要是一个个人项目,这样我可以测试一些 PHP 5.3 的优点,体验新技术,并让我有机会根据我的想法尝试一些东西。我还试图使这个框架尽可能轻量级,并减少不必要的 getter 和 setter 的数量。现在解决手头的问题。

框架的大部分已经完成,主要是它运行所需的所有核心类。问题出现在应用程序的入口点。我希望整个应用程序通过一个分支的单个核心对象运行。核心对象将通过类来扩展,以管理环境、配置、注册表、自动加载、路由等。您可以在下面看到这个“核心”对象,它被恰当地称为应用程序。

https://github.com/titon/titon/blob/42c88e36c29e3d8c697306fe68be18b3a 8FD2E70 /titon/source/Infrastruct.php

$app = new \titon\source\core\Application();

这个想法是,从应用程序中的任何位置,您都可以通过此 $app 变量访问核心对象。示例:(

我不能发布超过 1 个链接,因此请转到 Github 上的以下目录。/app/config/Setup.php 和 /app/modules/core/Bootstrap.php)

$app->environment->current();
$app->loader->includePath(array(__DIR__));
$app->registry->factory('titon\source\system\Controller');

但是现在我们遇到了全局问题变量,我不想使用它。我也喜欢尝试避免单例。

public function foobar() {
    global $app; // Eww
}

但我也不想使用静态类,因为我试图采用更面向对象的方法。我能想到的唯一解决方案是使用静态类属性来保存应用程序实例并在任何地方访问它,但我不喜欢那样。或者我可以一次又一次地将对象传递给它的子对象,但同样,不是粉丝。

Core::$app->router->detect(); // Meh
$this->setApplication($this); // Mehher

我很好奇 Zend 和 Symfony 如何解决这个问题。但在查看了他们的源代码之后,我无法进行反向工程并确定正确的入口点。此外,Zend 似乎会创建全局变量(Zend_Config 等),但我更喜欢有一个管理对象。 Symfony 2.0,我刚刚迷路了。至于 Cake、Solar、Fuel,似乎他们对这些类型的对象使用静态类。

现在我的首要问题是,你将如何解决这个问题?我想保留一个对象来实例化并可以随处访问,但这似乎不是一件容易处理的事情。如果需要的话,我愿意重写很多框架。

Before I begin, this framework is not meant to compete with Zend, Symfony, Cake or any other framework. It is primarily a personal project so that I may test out some PHP 5.3 goodies, experience new techniques and gives me the chance to try things under my idea. I am also trying to make this framework as lightweight as possible, and reduce the amount of unncessary getters and setters. Now for the problem at hand.

A bulk of the framework is done, primarily all the core classes required for it to run. The problem arises on the entry point of the application. I want the whole application to be run through a single core object which branches out. The core object will be extended with classes to manage environments, configuration, registry, autoloading, routing, etc, etc. You can see this "core" object below, it is aptly called Application.

https://github.com/titon/titon/blob/42c88e36c29e3d8c697306fe68be18b3a8fd2e70/titon/source/Infrastructure.php

$app = new \titon\source\core\Application();

The idea was that from anywhere in the application, you can access the core objects through this $app variable. Example:

(I cant post more than 1 link, so please go to the following directories on Github. /app/config/Setup.php and /app/modules/core/Bootstrap.php)

$app->environment->current();
$app->loader->includePath(array(__DIR__));
$app->registry->factory('titon\source\system\Controller');

But now we get into the problem of global variables, which I do not want to use. I also like to try and avoid Singletons.

public function foobar() {
    global $app; // Eww
}

But I also do not want to use static classes, as I was trying to go for a more OOP approach. The only solutions I can think of is using a static class property to hold the Application instance and access that everywhere, but I do not like that. Or I can pass the object down to its children over and over again, but again, not a fan.

Core::$app->router->detect(); // Meh
$this->setApplication($this); // Mehher

I was curious how Zend and Symfony approached this problem. But after looking through their source code, I could not backwards engineer and determine the correct entry point. Furthermore, it seemed Zend would created global variables all over (Zend_Config, etc), but I would prefer to have a managing object. Symfony 2.0, I just got lost. As for Cake, Solar, Fuel, it seems they are using static classes for these kind of objects.

Now my primary question is, how would you solve this? I would like to keep a single object to instantiate and be accessible everywhere, but it doesn't seem like an easy thing to handle. I am willing to rewrite a lot of the framework if need be.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月下伊人醉 2024-10-21 10:15:09

这个想法是,从应用程序中的任何位置,您都可以通过此 $app 变量访问核心对象。示例:

...

但是现在我们遇到了全局变量的问题,我不想使用它。我也喜欢尝试避免单例。

这对我来说似乎是矛盾的。

你知道为什么你不需要任何全局变量吗?是因为您在某处读到全局变量是一件坏事吗?

相反,您知道为什么需要一个可从应用程序中的任何位置访问的中心对象吗?

跟进

如果不清楚,这些都是反问句。从架构的角度来看,全局变量(任何形式)都是昂贵的。有人说邪恶。我认为这稍微忽略了一点 - 在任何应用程序中您都需要一定数量的全局变量(至少一个)。更进一步说,“全球”实际上是一个相对的事物。将变量视为具有不同的范围更有意义,其中全局变量位于连续体的一个极端,而局部临时变量位于另一个极端。如果您有一个包含所有其他对象的对象,那么我会将这些变量中的每一个视为有效的全局变量,即使它们在技术意义上可能并非如此。想一想。

至于灵丹妙药,您可以看看依赖注入。这是一种避免全局变量的方法,虽然有效,但会带来一定的复杂性成本。

The idea was that from anywhere in the application, you can access the core objects through this $app variable. Example:

...

But now we get into the problem of global variables, which I do not want to use. I also like to try and avoid Singletons.

That seems like a contradiction to me.

Do you know why you don't want any global variables? Is it because you read somewhere that global variables are a bad thing?

Conversely, do you know why you want a central object that is available from anywhere in your application?

Follow Up:

In case it wasn't clear, those were meant as rhetorical questions. From an architectural viewpoint, global variables (in any shape) are expensive. Some say evil. I think that's missing the point slightly - You need some amount of global variables in any application (At least one). To further muddy the waters, "global" is really a relative thing; It is much more meaningful to consider variables as having varying scopes, where global is on one extreme of the continuum and local, temporary variable at the other. If you have a single object containing all your other objects, then I would consider each of these variables as being effectively global variables, even though they may not be so in a technical sense. Think a bit about that.

As for a silver bullet, you could take a look at dependency injection. This is an approach to avoiding global variables that works, but has some cost in the form of complexity.

z祗昰~ 2024-10-21 10:15:09

PHP 未解决的老问题之一:如果不使用像 runkit 这样的扩展,就无法定义超全局变量。

我通常使用伪注册表来解决这个问题,即我定义一个class R,其中所有我想要全局定义的变量都定义为public static $var。我知道,这可能不是普通的 OOP 方法,但它效果很好。我认为 R::$var 已经尽可能短了。其他一切,例如依赖注入($this->var)或单例(R::getVar()),都更长。

One of PHP's old unresolved issues: One can't define superglobals, without using a extension like runkit.

I usually solve this with a pseudo-Registry, i.e. I define a class R with all variables I want to make global defined as public static $var. I know, this is probably not the vanilla-OOP approach, but it serves well. R::$var is as short as it get, I think. Everything else, like dependency injection ($this->var) or singleton (R::getVar()), is longer.

香橙ぽ 2024-10-21 10:15:09

避免全局变量的最佳解决方案是依赖注入。您可能需要创建一些容器。查看 Symfony 组件库。

您也可以尝试注册表模式。

The best solution to avoid global variables is dependency injection. You'll probably need to create some container. Look at the Symfony components library.

You may also try registry pattern.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文