Contact Us Forum Rules Search Archive
WebProWorld Part of WebProNews.com
Page One Link To Us Edit Profile Private Messages Archives FAQ RSS Feeds  
 

Go Back   WebProWorld > Webmaster, IT and Security Discussion > Web Programming Discussion Forum
Subscribe to the Newsletter FREE!


Register FAQ Members List Calendar Arcade Chatbox Mark Forums Read

Web Programming Discussion Forum Working with an API? Developing a plugin? Writing a Mod or script for your favorite blog, Web 2.0 site or Forum? Welcome.

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 10-10-2006, 07:46 PM
WebProWorld Pro
 

Join Date: Sep 2005
Location: Manchester, UK
Posts: 257
mikesmith76 RepRank 0
Default PHP Namespaces / Packages

Hi all,

As with all the ideas i usually have i was just driving home and a thought occurred to me - can namespaces / packages be replicated in php? For those of you that have ever programmed in java the concept should be familiar - simply import a package to import all the classes contained in that package.

I was thinking of creating a custom package loader class. Instead of using require / require_once to include classes directly i could group them into related packages and then call my package loader. I believe the Zend framework has a loader class, however i have never used Zend before and don't plan to for the moment anyway. Does anyone have experience with Zend who would care to comment?

Anyway guess the reason I am posting is i am wondering what you all think. Does anyone else use a similar method? Completely different systems for grouping classes are also welcome, i'm just trying to get ideas at the moment

thanks

mike
Reply With Quote
  #2 (permalink)  
Old 10-11-2006, 07:04 AM
kgun's Avatar
WebProWorld 1,000+ Club
 

Join Date: May 2005
Location: Norway
Posts: 5,402
kgun RepRank 3kgun RepRank 3kgun RepRank 3
Default

1. My classic reference on namespaces is:

Bjarne Strostrup (1994): "The Design and Evolution of C++" Addison-Wesley ISBN 0-201-54330-3 that has a complete chapter on it, chapter 17.

2. Namespaces in PHP are often related to XML paresers. You find more info on the site in my signature.

3. General search technique for PHP problems

KW's: problem in PHP

In this example

KW's: namespaces in PHP

or variations thereof.

4. If you make your own packages in PHP, I reccomend using unique indentifiers for your classes regardless of namespaces.

5. Always think: What is best for portability? Make your software as portable as possible. What happens to the directory structure if you move your code to another server?

6. Example of portable code: Always escape data from external sources.
<?php
function safeEscapeString($string)
{
if (get_magic_quotes_gpc()) {
return $string;
} else {
return mysql_escape_string($string);
}
}
?>

This function makes your code portable since it tests if magic_quotes_gpc is on. So it should be a member function in your class library.

$sql = "SELECT * from users
WHERE username='" . safeEscapeString($_POST['username']) . "'
AND password = '" . safeEscapeString($_POST['password']) . "';

Do you see the point?

For more info see the excellent book:
Harry Fuecks: The PHP Anthology: Object Oriented PHP Solutions volume I chapter 3, that also includes a useful class library, SPLIB (the name of the folder containing the class files).

Hereby reccomended.
Reply With Quote
  #3 (permalink)  
Old 10-11-2006, 08:06 AM
WebProWorld Pro
 

Join Date: Sep 2005
Location: Manchester, UK
Posts: 257
mikesmith76 RepRank 0
Default

I'm not really interested in how to code a Package system in php, that part is easy, i'm after thoughts of using such a system and whether anybody here has implemented something similar.

Quote:
What happens to the directory structure if you move your code to another server?
This is a really interesting point. Ideally my package structure should be independant of the actual file system structure, however i'm not sure how this could be implemented as of yet.

Quote:
I reccomend using unique indentifiers for your classes regardless of namespaces.
Another useful peice of advice. Most likely each class name would be prefixed by the name of the package it belongs to. However this could cause problems if i ever needed to move a class between packages.

The reasoning behind my idea is that the list of classes i have developed is growing on every project i work on. The organisation of these classes is a little loose at the moment, hence the packaging idea. Also the package loader class would remove the need for me to manually include every class file in a script.
Reply With Quote
  #4 (permalink)  
Old 10-11-2006, 08:52 AM
kgun's Avatar
WebProWorld 1,000+ Club
 

Join Date: May 2005
Location: Norway
Posts: 5,402
kgun RepRank 3kgun RepRank 3kgun RepRank 3
Default

Quote:
Originally Posted by mikesmith76
Most likely each class name would be prefixed by the name of the package it belongs to.
Yes, eg. by the name of the directory where the classes are located.

Quote:
Originally Posted by mikesmith76
However this could cause problems if i ever needed to move a class between packages.
Yes, if that class is used in a lot of other classes. Otherwise all you may need is to copy the class and change the prefix to the prefix of the new library (or directory). But that is against sound OOP, namely minimalism and code reuse.

It is always good to keep an updated map of your classes with subclasses (inheritance trees). Then the above task should not be so difficult. But try to avoid the problem by using unique names.

I think, I read somwhere that there is a better, more professional way to do it, but I can not remember where.

Useful link:
PHP: Into the Future

with sublink,

Ask the Experts a Question , namely:

Zeev Suraski

Andi Gutmans

both creators of PHP and the Zend Engine.

You can submit your question there and come back here and post what you found out, since it may be of interest to other WPW members.
Reply With Quote
  #5 (permalink)  
Old 10-11-2006, 11:10 AM
WebProWorld Pro
 

Join Date: Sep 2005
Location: Manchester, UK
Posts: 257
mikesmith76 RepRank 0
Default

Quote:
But that is against sound OOP, namely minimalism and code reuse.
I'm sorry I don't follow you here. What is against good OOP?

I've been having a look at PEAR and this seems to be organised into packages, however as far as i know they do not implement a package loading system. They seem to use the package name as a prefix of the class name, however the more i think about it the less convinced i become that this is a good idea

I'm supprised there hasn't been more interest in this thread, organising classes into packages seems an ideal way (to me anyway) of organising custom classes, especially if you have a large number of them.

I was thinking about how I would integrate this into PHP5's autoloading system and I think the only answer I can come up with is i wouldn't. Maybe use the autoloader to load the initial package loading class, everything else loaded via that.
Reply With Quote
  #6 (permalink)  
Old 10-11-2006, 12:42 PM
kgun's Avatar
WebProWorld 1,000+ Club
 

Join Date: May 2005
Location: Norway
Posts: 5,402
kgun RepRank 3kgun RepRank 3kgun RepRank 3
Default

Quote:
Originally Posted by mikesmith76
Quote:
But that is against sound OOP, namely minimalism and code reuse.
I'm sorry I don't follow you here. What is against good OOP?
Look at my post above. My proposed solution there was to copy a class (code) into another library only changing the class prefix. That is against code reuse. You shall not duplicate code. Duplicating code is the oposite of code reuse and breaks the principle of minimalism.


Quote:
Originally Posted by mikesmith76
I've been having a look at PEAR and this seems to be organised into packages, however as far as i know they do not implement a package loading system. They seem to use the package name as a prefix of the class name, however the more i think about it the less convinced i become that this is a good idea
I have PEAR installed. It follws with XAMPP and is automatically installed with the XAMPP in a subfolder. For example, PEAR has a DB_DATAOBJECT, DAO design pattern if you will, that makes an API to your MySQL database, so you need not write SQL statements embedded in PHP code.

Quote:
Originally Posted by mikesmith76
I'm supprised there hasn't been more interest in this thread, organising classes into packages seems an ideal way (to me anyway) of organising custom classes, especially if you have a large number of them.
Yes that is the idea behind code reuse. Silence is not the same that people is not interested in the thread, but this forum is not the most visited at WPW.

Namespaces is about scope. One solution is to define a namespace scope and use the scope resolution operator :: to access memebers from that namespace that may be classes.

Example:

Namespace MyNameSpace {

Class MyClass ...

....

}

Then

MyNameSpace::MyClass

is a unique entiety within your code and avoids name conflicts.

Somebody else has launched the idea that a namespace should be a class, but that solutiong was regarded as a bad idea in C++. PHP is a C like (derived) language. Sooner a class is a form of namespace. But in the end everything is a pattern, the BETA view.

I think you should have no problem using multiple external well known libraries like PEAR and your own library as long as you use unique names in your own libraries.

Solution that was left in C++, since it was not good enough, but compared to BETA (see the site in my signature for more info), C++ will probably never get good enough and compared to C++, PHP (and Java) will probably neither get good enough.

Class Namespace
{Some code here }

Remember to use public and private if you use PHP 5.0.
Reply With Quote
  #7 (permalink)  
Old 10-11-2006, 07:38 PM
WebProWorld Pro
 

Join Date: Sep 2005
Location: Manchester, UK
Posts: 257
mikesmith76 RepRank 0
Default

Quote:
Namespace MyNameSpace {

Class MyClass ...

....

}

Then

MyNameSpace::MyClass
This is a very interesting idea. However It would result in one large file containing several classes, not good for ease of modification in my opinion.

Thanks for your posts kgun, you've given me a few ideas for me to think about. I'm going to give this project some more thought and i will post back what i come up with.
Reply With Quote
  #8 (permalink)  
Old 11-04-2006, 08:42 PM
kgun's Avatar
WebProWorld 1,000+ Club
 

Join Date: May 2005
Location: Norway
Posts: 5,402
kgun RepRank 3kgun RepRank 3kgun RepRank 3
Default

Another possibility is to go around the problem in case of simple name collitions. You may change the include_path at runtime.

Here is an example:

config.php

<?php
/*
ini_set Sets the value of the given configuration option. Returns the old value on success, FALSE on
failure. The configuration option will keep this new value during the script's execution, and will be
restored at the script's ENDING.
Note: magic_quotes_runtime is not the same as magic_quotes_gpc.
See the PHP manual Appendix G. php.ini directives for more information.
http://www.php.net/manual/en/ini.php#ini.list
*/
ini_set('include_path',ini_get('include_path') . '/SPLIB:' . '/pear:');
ini_set('display_errors', "1"); // Changeable PHP_INI_ALL
ini_set('magic_quotes_runtime', "0"); // Changeable PHP_INI_ALL

// ini_set('magic_quotes_gpc', "0"); Changeable PHP_INI_PERDIR Entry can be set in php.ini, .htaccess or httpd.conf
// ini_set('short_open_tag', "0"); Changeable PHP_INI_PERDIR Entry can be set in php.ini, .htaccess or httpd.conf
?>

You can change include path when and where you want at run time.

You can test configurating settings with a file like this:

configtest.php

<?php
echo ( '<pre>' );
echo 'Include_path = ' . ini_get('include_path') . "\n";
echo ( '</pre>' );
echo ( '<pre>' );
echo 'Magic_quotes = ' . ini_get('magic_quotes_gpc') . "\n";
echo ( '</pre>' );
echo ( '<pre>' );
echo 'Short_open_tag = ' . ini_get('short_open_tag') . "\n";
echo ( '</pre>' );
echo ( '<pre>' );
echo 'register_globals = ' . ini_get('register_globals') . "\n";
echo ( '</pre>' );
echo ( '<pre>' );
echo 'post_max_size = ' . ini_get('post_max_size') . "\n";
echo ( '</pre>' );
echo ( '<pre>' );
echo 'display_errors = ' . ini_get('display_errors') . "\n";
echo ( '</pre>' );
echo ( '<pre>' );
echo 'post_max_size+1 = ' . (ini_get('post_max_size')+1) . "\n";
echo ( '</pre>' );

require_once ('config.php'); // Note the difference for include path.

echo ( '<pre>' );
echo 'Include_path = ' . ini_get('include_path') . "\n";
echo ( '</pre>' );
echo ( '<pre>' );
echo 'Magic_quotes_runtime = ' . ini_get('magic_quotes_runtime') . "\n";
echo ( '</pre>' );

//$inis = ini_get_all();
//print_r($inis);
?>

So if you have a standard include path, you may change that at run time for some applications. May be this confuses more than it clears. And it does not solve the general problem with name conflicts.
Reply With Quote
  #9 (permalink)  
Old 11-04-2006, 09:50 PM
kgun's Avatar
WebProWorld 1,000+ Club
 

Join Date: May 2005
Location: Norway
Posts: 5,402
kgun RepRank 3kgun RepRank 3kgun RepRank 3
Default

It should be:

ini_set('include_path',ini_get('include_path') . '../SPLIB:' . '../pear:');

in my config.php file.
Reply With Quote
  #10 (permalink)  
Old 11-11-2006, 11:42 AM
kgun's Avatar
WebProWorld 1,000+ Club
 

Join Date: May 2005
Location: Norway
Posts: 5,402
kgun RepRank 3kgun RepRank 3kgun RepRank 3
Default

May be wild thoughts:

You have n libraries. Every library must be in your path. E.g. like this simple example with two external libraries:

config.php

<?php
ini_set('include_path',ini_get('include_path') . '../SPLIB:' . '../pear:');
?>

You may have the most important libraries in the path specified in your php.ini file. ini_get( ) takes care of that. ini_set sets the rest of the library paths you need. You may have more than one such configuration file, depending on the libraries you need in that project.


PHP is very flexible. A function may take an array as an argument. Each element in the array may be a new array. So here is my proposal:

1. You have n libraries, L1 ... Ln.
2. Library i, Li has Ki classes.

Write a class


SuperLibrary {

with constructor

Function SuperLibrary ($LibraryNames) {

some code here. }

Where $LibraryNames = array (

$library1,
$library2,
....
$libraryn);

$libraryi=array(ClassI1,...,ClassIk); i=1, ..., n.

The arrays are associative.

Now you have an overview of all the classes in all the libaries. That information may be stored in a database, so the array information is pulled from the database.

Then

SuperClass(ij) = Library(i)::Class(j);

If you use PHP patterns like the factory method, adapter pattern etc. this may be done seamless.

There may of course be overlap of the classes, but now each SuperClass has a unique name SuperClass(ij).

Inspiration:
Harry Fuechs: (may 2005):
The PHP Anthology: Object Oriented PHP Solutions I and II volume II chapter 7. "Design patterns."

More generally, without having read the book:

Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (1995): "Design Patterns: Elements of Reusable Object-Oriented Software." Addison-Wesley Professional ISBN 0201633612

P.S. More generally a PHP function may take m parameters where each parameter is an array of arrays of arrays ... You soon get memory problems if you do not use references. Combined with a MySQL database, arrays are very flexible, since records (rows) in the tables in the database may be written directly into indexed or associative arrays. In addition the elements may be different objects. It is difficult to make it more flexible / general than this since PHP is loosely typed.
Reply With Quote
Reply

  WebProWorld > Webmaster, IT and Security Discussion > Web Programming Discussion Forum
Tags: , ,



Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Search Engine Optimization by vBSEO 3.2.0