GLOBAL

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

I Use Globals

I do I do all the time!
1
4%
They're useful sometimes
3
13%
I use them here and there but try not
7
30%
never use, why would i?
12
52%
 
Total votes: 23

Z3RO21
Forum Contributor
Posts: 130
Joined: Thu Aug 17, 2006 8:59 am

Post by Z3RO21 »

I use super global arrays such as $_GET and $_POST, but as for implementing my own globals I prefer to use a registry class.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

stereofrog wrote:
Oren wrote:I'm sorry, but that's a stupid answer - simply because there is no good answer.
Please don't lower the level of the discussion with arguments like this.
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.
I'm not sure what you're trying to say here. Can you provide an example of your approach?
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.

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.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

stereofrog wrote:
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.
I'm not sure what you're trying to say here. Can you provide an example of your approach?
The question is: What are the security, design and maintenance differences between::

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();
And:

Code: Select all

//Application.php:
class Application {
function a() {}
function b() {}
}

//index.php:
include 'Application.php';
$app = new Application();
$app->a();
$app->b();
Considerations might be things like exploitablity, memory usage, extra method call overhead, obviousness to other programmers, etc.
(#10850)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

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. :P

I assume that was for the sake of brevity or was that part of the problem? :)
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

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

Code: Select all

$fooBar = FooBar_Application();
$fooBar->run();
1 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 is

Code: Select all

FooBar_Application::init();
which 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.
User avatar
Oren
DevNet Resident
Posts: 1640
Joined: Fri Apr 07, 2006 5:13 am
Location: Israel

Post by Oren »

stereofrog wrote:Please don't lower the level of the discussion with arguments like this.
I'm sorry, but there isn't much to say here, it's pretty much straight forward.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

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
Why is it dangerous to use a constructor for object construction? The name alone implies it's very use. :)
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.
Admittedly I am not following this thread very closely and have no idea where that came from... :P

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". :P

What was the point of this topic? :roll:
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

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.

Code: Select all

define("FRAMEWORK_ROOT", "/somewhere/in/here");
require_once FRAMEWORK_ROOT . "/lib/Core/Context.php";
Core_Context::getInstance()->getController()->dispatch();
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.
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

arborint wrote: The question is: What are the security, design and maintenance differences between::

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();
And:

Code: Select all

//Application.php:
class Application {
function a() {}
function b() {}
}

//index.php:
include 'Application.php';
$app = new Application();
$app->a();
$app->b();
Considerations might be things like exploitablity, memory usage, extra method call overhead, obviousness to other programmers, etc.
Let's consider the more realistic yet still simplified example:

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;
	}
}
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.
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

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

Code: Select all

$fooBar = FooBar_Application();
$fooBar->run();
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()?
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.
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.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

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.
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.

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();
And:

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;
For example, a simple difference is that the first example adds the overhead of an object instantiation and function call every request. So that is a slight performance negative. What are the security, design, maintainablity and other issues.
(#10850)
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

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.
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

arborint wrote: Again the question is not if you think so.
Of course it is. ;) We are here to share our personal opinions. Nobody claims to possess the absolute truth.
So what are the real differences related to security, design and maintenance between the following index.php scripts?
Sorry, I don't see your point. Are you advocating a procedural approach? You can not be serious. ;)
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

stereofrog wrote:Sorry, I don't see your point. Are you advocating a procedural approach? You can not be serious. ;)
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 why ;)

I can think of another reason though. Unit Testing is easier if it's done my method invocation.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

stereofrog wrote:Of course it is. ;) We are here to share our personal opinions. Nobody claims to possess the absolute truth.
Yes we express our opinions, but the validity of those opinions are based on the facts that back them up.
stereofrog wrote:Sorry, I don't see your point. Are you advocating a procedural approach? You can not be serious. ;)
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.
(#10850)
Post Reply