PHP seems to have serious namespace issues when scripts are broken into multiple files. For instance, if I have an HTML file that needs to run functions or read variables from a PHP file, I can’t treat the PHP file as a class with member functions/variables. I have to run the PHP files and then make assumptions about the names of the functions/variables (as globals). What’s more, PHP doesn’t seem to object if globals are overwritten by other PHP files.
Am I missing something here (I'm very newbie)?
How do we keep the namespace clean with multiple PHP files?
Moderator: General Moderators
If I read that right.. you are saving a class (for example MyClass) in the file MyClass.php then trying to call the class without including it? ala Java - PHP does not do this, you must use require/include functions to use the file (and it's contents as PHP script)
And are you also using the Variable Scope incorrectly?
PHP is a scripting language that has aspects of OOP. You must "gather" all the relevant bits of PHP script that you need as at run time to form a big script in memory. So all your class definitions, function definitions etc. need to be included before you can use them.
As for the globals problem.. well, using global $var; in a class can be problematic if you are not careful with the naming of said variables/properties. An example for a weak name:
A better example:
or even better, use a constant so that even if done by coincidence, you or future developers will know immediately by means of a "constant already defined" error.
Sorry if this is not what you refer to.. I don't fully understand what you mean.
And are you also using the Variable Scope incorrectly?
PHP is a scripting language that has aspects of OOP. You must "gather" all the relevant bits of PHP script that you need as at run time to form a big script in memory. So all your class definitions, function definitions etc. need to be included before you can use them.
As for the globals problem.. well, using global $var; in a class can be problematic if you are not careful with the naming of said variables/properties. An example for a weak name:
Code: Select all
class MyClass
{
function MyClass ()
{
global $result; // contains .. oh I dunno, a setting for the format of a result.
//do something with $result;
}
}
$result = mysql_query("SELECT * FROM `table`");
MyClass::MyClass(); //error - $result no longer contains the value of the setting.Code: Select all
class MyClass
{
function MyClass ()
{
global $MyClassResultFormat; // contains .. oh I dunno, a setting for the format of a result.
//do something with $MyClassResultFormat;
}
}
$result = mysql_query("SELECT * FROM `table`");
MyClass::MyClass(); //no error - $MyClassResultFormat is not likely to be used by coincidence.Sorry if this is not what you refer to.. I don't fully understand what you mean.
- Chris Corbyn
- Breakbeat Nuttzer
- Posts: 13098
- Joined: Wed Mar 24, 2004 7:57 am
- Location: Melbourne, Australia
Re: How do we keep the namespace clean with multiple PHP fil
Just to back Jenk up since I read what you've said the same way Jenk has.
If you really want to prevent overriding your globals you can always do some checking before you assign values to them too.
This is how PHP works yes... it's not like C or Java, the contents of the files are pulled into the scripts inline.BlindMan wrote:PHP seems to have serious namespace issues when scripts are broken into multiple files. For instance, if I have an HTML file that needs to run functions or read variables from a PHP file, I can’t treat the PHP file as a class with member functions/variables. I have to run the PHP files and then make assumptions about the names of the functions/variables (as globals).
Correct, that's why it's *usually* ideal to minimize globals as much as possible by factorising into many classes etc. As Jenk says, constants will error if you try to overwrite. You can use define() for globally accessible constants, or the "const" keyword for static constants in PHP5 OOP.BlindMan wrote:What’s more, PHP doesn’t seem to object if globals are overwritten by other PHP files.
Am I missing something here (I'm very newbie)?
If you really want to prevent overriding your globals you can always do some checking before you assign values to them too.
I believe I found a solution, but first let me clarify the problem...
I do understand that files are run in-line and that's how you get data/function definitions from other files.
The problem is that the code in one file must make assumptions about the names of variables/functions in order to use code in other files, and I thought that these assumptions applied to the global namespace. In the example provided, “MyClassResultFormat” is a good name because it ‘seems unique enough’ to prevent a namespace collision. I dislike situations like this where there’s nothing to protect us but convention—especially when global variables can be overwritten by subsequently included PHP files.
Solution...?
If we include a PHP file from within the scope of a function, and the variables within the file are not “global”, these variable will not affect any of the global variables of our main file (protects our global namespace).
For Example...
Given this solution, it seems that PHP files should interface with each other through variables, not functions, when possible. Function names have only one, global namespace.
I do understand that files are run in-line and that's how you get data/function definitions from other files.
The problem is that the code in one file must make assumptions about the names of variables/functions in order to use code in other files, and I thought that these assumptions applied to the global namespace. In the example provided, “MyClassResultFormat” is a good name because it ‘seems unique enough’ to prevent a namespace collision. I dislike situations like this where there’s nothing to protect us but convention—especially when global variables can be overwritten by subsequently included PHP files.
Solution...?
If we include a PHP file from within the scope of a function, and the variables within the file are not “global”, these variable will not affect any of the global variables of our main file (protects our global namespace).
For Example...
Code: Select all
<!-- File: PersonIndex.html -->
<?php
$person = new Person("foo");
// if we wrap the 'include' with a function, we prevent the included file
// from affecting the global variables ('$person')
function LoadPerson1()
{
include("Person1.php");
return $person;
}
function LoadPerson2()
{
include("Person2.php");
return $person;
}
$person1 = LoadPerson1();
$person2 = LoadPerson2();
// $person is still "foo"
?>
<!-- File: Person1.html -->
<?php
$person = new Person("one");
?>
<!-- File: Person2.html -->
<?php
$person = new Person("two");
?>
Last edited by BlindMan on Sun Dec 18, 2005 5:35 pm, edited 1 time in total.
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
In your given example, the seperation of files is not necessary, it can be condensed to:
I know it's only an example, but maybe this is an indication of where you might be doing things wrong and not need to execute the instantiation of an object in a serperate file like that.
(also, a pedantic and worthless point, you have include("person1/2.php"); but have <!-- File person1/2.html --> :p)
BTW, this next suggestion I am not sure about, but try returning $person by reference, I know PHP now does this "by default" but it's worth a try..
It's also probably not a good idea to contain class definitions or object instantiations inside a function. Don't quote me on it though.
Code: Select all
<?php
$person = new Person("foo");
$person1 = new Person("one");
$person2 = new Person("two");
?>(also, a pedantic and worthless point, you have include("person1/2.php"); but have <!-- File person1/2.html --> :p)
BTW, this next suggestion I am not sure about, but try returning $person by reference, I know PHP now does this "by default" but it's worth a try..
Code: Select all
<?php
function & LoadPerson1 () {
include("person1.php");
return $person;
}
$person1 =& LoadPerson1();
?>