Page 3 of 3

Posted: Sun Jul 08, 2007 5:16 pm
by Ollie Saunders
Hockey wrote:Why is it dangerous to use a constructor for object construction? The name alone implies it's very use.
I think you misread me:
I wrote:Well it's probably quite dangerous to do anything more than required for construction of the object in the constructor.
Hockey wrote: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.
Yeah I do that too. If there are more than 3 characters so that satisfies my code standard.
d11wtq wrote:I like to do something a bit like what ~ole just did, albeit selecting an approriate controller first.
You and I do differ there. I have a series of environment objects such as development, production, testing etc. that each pull in their own front controllers and one object that decides which environment to use.
stereofrog wrote: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()?
I don't agree that it is possible for a constructor to create side-effects. It's purpose it to set up the initial state so there was no state beforehand. However it is not the job of the constructor, necessarily, to execute the primary action of the class and given those two responsibilities and I think the difference between __construct() and run() is quite clear cut and it is useful to separate. As for exception handling, I think that problem can be all but eradicated by only placing code that is likely to throw exceptions at runtime in places where it can be easily caught.
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.
Sadly not all libraries subscribe to this so how do I avoid collisions with them? I couldn't, for instance, create a class called HtmlReporter in my application because SimpleTest has already defined that. Additionally I don't see the chance of combining multiple applications as an impossibility. Protecting yourself from these problems is an good, easy habit to get into and I see no reason to stop.

The main problem I see with globals is that they can be read and written to from anywhere. This means that if you use globals your entire application it dependent on each any everyone of them. Also it is not obvious where reads and write happen, the whole principle of divide and conquer coding breaks down. It's like having several people working on a small desk, each person is shuffling about bits of paper in a bid to get work done; moving other people's work in the process. As a result the individuals involved are forever losing things they and they keep having to stop and ask each other where x object has gone. In this regard global registries, especially ones accessible via static methods, are not much better.

Even if other platforms/frameworks have used them, statics aren't very object orientated. I've spoken to people working on in relatively fast paced teams who say the average lifetime of a static is about 2 or 3 months and then they need to be replaced and usually they have to resort to lengthy find/replace sessions to do this.

I like to keep my globals down to as few as possible because it's the best leg to start on. If you start your application by using several globals you, or someone else, is going to continue to do so. Similarly is you start by using, several statics as an alternative to globals, then they are probably going to multiply. Both are bad, but unfortunately you've got to have some of them. There's a trade-off here between the two. I'm on the fence. Statics can't be reassigned later but represent poor objectification. I'd say avoid both where possible but they are an inevitability.

Posted: Sun Jul 08, 2007 6:38 pm
by superdezign
I'm finding this discussion very useful. I'm refactoring my blog application right now, and these opinions are enlightening.

I agree completely that __construct() constructs / initializes. There's really no way to justify otherwise. If __destruct() nullifies object properties, __construct() should initialize them.


On the topic of globals, I'd like to know how you guys feel about configuration files. I've seen them done through definitions before, as well as just creating global variables that are later loaded into a constructor (or something else that needs it). However, I was unaware that globals caused a security hole. What would be a good way to do a configuration file then? I was considering that it be a regular text file that I could parse, but then it'd be visible through the browser. Any thoughts?

Posted: Sun Jul 08, 2007 7:12 pm
by alex.barylski
superdezign wrote:However, I was unaware that globals caused a security hole.
Globals themselves don't. It when PHP had register_globals setting enabled they could potentially cause trouble.

register_globals allowed an attacker to set a variables properties via GPC (likely through GET) like this:

Code: Select all

index.php?auth=true
PHP would bring that variable typically set inside $_GET['auth'] as a normal local variable. If you had some code which check the $auth variable without first initializing it, you could circumvent an authentication system quit easily.

index.php?auth=true

Code: Select all

if($auth == true){
  echo 'Carry out some privileged stuff';
}
else
  echo 'You must login first';
Super GLOBALS are not (that I am aware of) a security threat.
superdezign wrote:What would be a good way to do a configuration file then? I was considering that it be a regular text file that I could parse, but then it'd be visible through the browser. Any thoughts?
Couple ways to solve this issue.

1) Protect the 'conf' directory with .htaccess
2) Store config file outside of docroot

Storing configuration values inside a GLOBAL requires the use of PHP scripts which are obviously evaluated before being sent to browser. Those settings have to eventually make it into your application namespace (unless you have an accessor function which fetchs the file and value each time - which would be baaaad on performance) as GLOBALS or SESSIONS, so long as you add a namespace to keep them uniquely global. Meh. Alternatively you could use a registry object, but I personally prefer to keep that for objects and such.

I pack configuration/etc inside the SESSION super globals. Why?

1) They are persisted across requests by simply calling session_start() - single initialization
2) They are accessible always, without having to include the proper registry object, etc.

#2 may need some explaining. Sometimes (especially when integrating third party apps) I simply cannot be bothered to include neat and tidy registry objects. For instance, when you send POST requests to an external script which needs to validate your user.

checkuser.php

Code: Select all

<?php
  session_start();

  if($SESSION['auth'] == true)
    echo 'Carry out stuff';
  else 
    echo 'Redirect back to wherever';
Relying on a super global like SESSION lets you avoid messy file inclusions, etc. If you used a custom registry object you need to include it in the file each time you use it...PITA. Or you could use auto_prepend (implicit coding gets you into trouble).

It's far easier in terms of maintenance to just use the super global.

Globals become an issue when they are used like regular variables, being (re)set in random places in your code. Storing things like configuration settings, language codes, etc, that are initialized once and should not be touched again, should be fine IMHO.

Note: I did some profile test a whiles back versus loading language files from an INI file as opposed to keeping them as GLOBALS and initializing the GLOBALS via INI was actually faster. Parsing PHP is naturally slower than parsing a simple file like INI, so it makes sense to keep configs inside simple text files.


Cheers :)