GLOBAL
Moderator: General Moderators
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
I'm not sure I follow the argument with keeping functionality inside a constructor or directly inside index.php, but I agree with your statement above.stereofrog wrote:Please don't lower the level of the discussion with arguments like this.Oren wrote:I'm sorry, but that's a stupid answer - simply because there is no good answer.
I'm not sure what you're trying to say here. Can you provide an example of your approach?Doing that as opposed to doing what is in Application's constructor cannot be justified, it's pretty much like taking everything in the index.php file and throw it into some other file and then include this other file from index.php - this will take the same time as without doing it at best, and will probably be slower at worst.
Is Application just a moniker for application engine, etc?
In either case, I think it depends on the architecture of your application.
For example, index.php I usually reserve for application specifics. An easy way to allow users to customize the application (authentication checks, output filtering, etc). Application objects would be considered a core part of the system. Basically, index.php is where I keep most "truely" global operations.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
The question is: What are the security, design and maintenance differences between::stereofrog wrote:I'm not sure what you're trying to say here. Can you provide an example of your approach?oren wrote:Doing that as opposed to doing what is in Application's constructor cannot be justified, it's pretty much like taking everything in the index.php file and throw it into some other file and then include this other file from index.php - this will take the same time as without doing it at best, and will probably be slower at worst.
Code: Select all
//Application.php:
class Application {
function __construct() {
$this->a();
$this->b();
}
function a() {}
function b() {}
}
//index.php:
include 'Application.php'; // here or in autoprepend -- same effect
new Application(); // run __construct();Code: Select all
//Application.php:
class Application {
function a() {}
function b() {}
}
//index.php:
include 'Application.php';
$app = new Application();
$app->a();
$app->b();(#10850)
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
There is no difference in the two examples you show, except that in one, the ctor() calls the methods so the object is self-initializing whereas the second example, requires explicit initialization...
I fail to see any benefits, security problems, etc...
What approach you use would depend on the problem
If Application requires a() & b() to be called before object use then yea...calling them in ctor() is kind of good practice. Otherwise, they are optional and probably best left in the hands of the client programmer...
One thing I did notice in your example, was that #1 would be a usability nightmare because Application() instance isn't assigned to variable so it would be mighty difficult to use anywhere.
I assume that was for the sake of brevity or was that part of the problem?
I fail to see any benefits, security problems, etc...
What approach you use would depend on the problem
If Application requires a() & b() to be called before object use then yea...calling them in ctor() is kind of good practice. Otherwise, they are optional and probably best left in the hands of the client programmer...
One thing I did notice in your example, was that #1 would be a usability nightmare because Application() instance isn't assigned to variable so it would be mighty difficult to use anywhere.
I assume that was for the sake of brevity or was that part of the problem?
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
Well it's probably quite dangerous to do anything more than required for construction of the object in the constructor. Personally I would opt for1 single variable really presents no problems as it is easy to find and change or wrap in a function.
Although what I'm actually doing at the moment iswhich isn't actually a very good idea, say if you need to manage multiple applications. The constructor approach suffers from the same problems but is more confusing to the reader.
For the same reason why I avoid globals I wouldn't actually use a class called "Application", all classes should have at least a three letter prefix to prevent the risk of name clashing.
Code: Select all
$fooBar = FooBar_Application();
$fooBar->run();Although what I'm actually doing at the moment is
Code: Select all
FooBar_Application::init();For the same reason why I avoid globals I wouldn't actually use a class called "Application", all classes should have at least a three letter prefix to prevent the risk of name clashing.
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Why is it dangerous to use a constructor for object construction? The name alone implies it's very use.ole wrote:Well it's probably quite dangerous to do anything more than required for construction of the object in the constructor. Personally I would opt for
Admittedly I am not following this thread very closely and have no idea where that came from...ole wrote:For the same reason why I avoid globals I wouldn't actually use a class called "Application", all classes should have at least a three letter prefix to prevent the risk of name clashing.
I agree, at least in adding extra namespace to each class name until namespaces are standard part of PHP. Whether three characters or not. I usually prefix my classes with the code name of the project.
class Omaha_Application
Each major version gets a new codename so version 2:
class Juno_Application
As a war film junkie I use code names that pay homage to that amazing time in our world history. I also use airplanes, stars or anything else I consider "cool".
What was the point of this topic?
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
In other languages you'll often see a static method call as the dispatcher.
C(#/++) uses a statically called main() method.
Java/Desktop/CLI uses a static main() method.
PHP doesn't enforce anything which is arguably flexible, or messy.
Java Servlets use doGet(), doPost(), doPut() etc methods, called on an instance of HttpServlet.
I'm not sure what the internals of a Java servlet being dispatched are, but the instance of HttpServlet needs to come from somewhere.
I like to do something a bit like what ~ole just did, albeit selecting an approriate controller first.
I don't think it's bad to use globals just as a launch point though. It's only down to preference that I dispatch in this way.
C(#/++) uses a statically called main() method.
Java/Desktop/CLI uses a static main() method.
PHP doesn't enforce anything which is arguably flexible, or messy.
Java Servlets use doGet(), doPost(), doPut() etc methods, called on an instance of HttpServlet.
I'm not sure what the internals of a Java servlet being dispatched are, but the instance of HttpServlet needs to come from somewhere.
I like to do something a bit like what ~ole just did, albeit selecting an approriate controller first.
Code: Select all
define("FRAMEWORK_ROOT", "/somewhere/in/here");
require_once FRAMEWORK_ROOT . "/lib/Core/Context.php";
Core_Context::getInstance()->getController()->dispatch();- stereofrog
- Forum Contributor
- Posts: 386
- Joined: Mon Dec 04, 2006 6:10 am
Let's consider the more realistic yet still simplified example:arborint wrote: The question is: What are the security, design and maintenance differences between::And:Code: Select all
//Application.php: class Application { function __construct() { $this->a(); $this->b(); } function a() {} function b() {} } //index.php: include 'Application.php'; // here or in autoprepend -- same effect new Application(); // run __construct();Considerations might be things like exploitablity, memory usage, extra method call overhead, obviousness to other programmers, etc.Code: Select all
//Application.php: class Application { function a() {} function b() {} } //index.php: include 'Application.php'; $app = new Application(); $app->a(); $app->b();
Code: Select all
class Application
{
function __construct() {
$lc = new LocalConfig();
if($lc->rewrite_method == '404') {
$router = $lc->get('router_404');
} else {
$router = $lc->get('router');
}
$request = $lc->get('request');
list($ac_name, $action) = $router->map($request);
$ac = $lc->get('ac_name');
if(!$ac) {
$ac = $lc->get('error_controller');
$action = 'controller_not_found';
}
$html = $ac->run($lc, $action, $request);
$html = $router->url_rewrite($html);
echo $html;
}
}- stereofrog
- Forum Contributor
- Posts: 386
- Joined: Mon Dec 04, 2006 6:10 am
Good approach, however there are two problems with it. First, it's often hard to separate "what is required for construction" (strictly speaking, nothing) from "what is required for running" (strictly speaking, everything). Requiring the constructor to have absolutely no side effects doesn't seem practical to me. Second, if the constructor fails, where would you handle an exception: in __construct() or in run()?ole wrote:Well it's probably quite dangerous to do anything more than required for construction of the object in the constructor. Personally I would opt forCode: Select all
$fooBar = FooBar_Application(); $fooBar->run();
From my POV, prefixing (aka "poor man's namespaces") is useful for common library classes, not for the application ones, especially the main Application class, which is unique by definition.For the same reason why I avoid globals I wouldn't actually use a class called "Application", all classes should have at least a three letter prefix to prevent the risk of name clashing.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Again the question is not if you think so. It is whether there are some sort of reasonable security, performance or maintainablity reasons to do so. I think this is a very worthwhile subject PHP developers to think through. I think use of the global scope is something that we ought to have so best practice guidelines for. Certainly in the past with register_globals defaulting to ON there were security concerns regarding uninitialized variables in the global scope. But register_globals has defaulted to OFF for several years now.stereofrog wrote: Let's consider the more realistic yet still simplified example:
Add persistence, plugin support, CLI support and anything else to your taste. Would it be practical to put all this into global scope? I don't think so.
So what are the real differences related to security, design and maintenance between the following index.php scripts?
Code: Select all
class Application
{
function __construct() {
$lc = new LocalConfig();
if($lc->rewrite_method == '404') {
$router = $lc->get('router_404');
} else {
$router = $lc->get('router');
}
$request = $lc->get('request');
list($ac_name, $action) = $router->map($request);
$ac = $lc->get('ac_name');
if(!$ac) {
$ac = $lc->get('error_controller');
$action = 'controller_not_found';
}
$html = $ac->run($lc, $action, $request);
$html = $router->url_rewrite($html);
echo $html;
}
}
new Application();Code: Select all
$lc = new LocalConfig();
if($lc->rewrite_method == '404') {
$router = $lc->get('router_404');
} else {
$router = $lc->get('router');
}
$request = $lc->get('request');
list($ac_name, $action) = $router->map($request);
$ac = $lc->get('ac_name');
if(!$ac) {
$ac = $lc->get('error_controller');
$action = 'controller_not_found';
}
$html = $ac->run($lc, $action, $request);
$html = $router->url_rewrite($html);
echo $html;(#10850)
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
If you dump all code in a procedural fashion in the index.php file then say for example you decide to allow elements of your application to be interacted with using CLI you'd have to write a new equivalent of index.php with CLI specific launch settings. If you encapsulate that code into a class somewhere then you can extend that class and override selected parts for CLI.
Another consideration is that if you're going to start writing code in your index.php file like that, where do you draw the line between what's allowed in the global scope and what isn't? Is it perhaps keeping the tin open to ad-hoc elements of code being dumped into the file?
I agree that it's worth discussing the nitty-gritty of what exactly is wrong with using globals during the dispatch process though... when you think about it, most of the considerations you come up with are not particularly relevant.
Another consideration is that if you're going to start writing code in your index.php file like that, where do you draw the line between what's allowed in the global scope and what isn't? Is it perhaps keeping the tin open to ad-hoc elements of code being dumped into the file?
I agree that it's worth discussing the nitty-gritty of what exactly is wrong with using globals during the dispatch process though... when you think about it, most of the considerations you come up with are not particularly relevant.
- stereofrog
- Forum Contributor
- Posts: 386
- Joined: Mon Dec 04, 2006 6:10 am
Of course it is.arborint wrote: Again the question is not if you think so.
Sorry, I don't see your point. Are you advocating a procedural approach? You can not be serious.So what are the real differences related to security, design and maintenance between the following index.php scripts?
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
I think ~arborint is trying to encourage a discussion that gets right down to the core principals surrounding why *not* to use globals. Nobody's saying you should, or should not, but without being able to answer *why* it's bad to use them you have ton wonder whystereofrog wrote:Sorry, I don't see your point. Are you advocating a procedural approach? You can not be serious.
I can think of another reason though. Unit Testing is easier if it's done my method invocation.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Yes we express our opinions, but the validity of those opinions are based on the facts that back them up.stereofrog wrote:Of course it is.We are here to share our personal opinions. Nobody claims to possess the absolute truth.
But it is your exact code! Your code is procedural within the constructor. So that is not really and argument. That is why I asked what the real difference is. I am honestly not trying to be an ass. I think this is an important discussion that can help us understand the current best practice.stereofrog wrote:Sorry, I don't see your point. Are you advocating a procedural approach? You can not be serious.
(#10850)