#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Location
    Ithaca
    Posts
    68
    Rep Power
    2

    My PHP Collections Framework Project


    Well lately I've been working on this PHP collections framework. These data structures are definitely based on Java and C#'s, although the actual code may differ significantly due to the fact that PHP is after all, not Java or C#. The version 1.0 of this project has been completed, and in future I will be extending beyond the basic data structures to provide more functionality.

    I believe it will be quite useful for a highly object oriented application, it is a very effective way to handle collections of objects. This current version contains most widely used data structures such as HashSet, ArrayList, LinkedList, Stack, Queue, Deque, HashMap, TreeMap, I've carried out extensive beta testing to make sure they work out the way they should.

    To see how the Collections framework does its job in practice, I've provided two example using ArrayList and HashMap. The demo code consists of some Tales of Symphonia reference, which I think is fun:


    ArrayList: (preview @ http://mysidiarpg.com/site/collection/arraylistdemo.php)
    PHP Code:
    <?php

    require "autoloader.php";

    $seraphim = new ArrayList(4);    
    $mithos = new String("Mithos Yggdrasill");
    $martel = new String("Martel Yggdraill");
    $yuan = new String("Yuan Kafei");
    $kratos = new String("Kratos Aurion");

    $seraphim->add($martel);
    $seraphim->add($yuan);
    $seraphim->add($kratos);
    $seraphim->insert(0$mithos);
    $seraphIterator $seraphim->iterator();

    echo 
    "Cruxis has the following Four Seraphim:<br>";
    while(
    $seraphIterator->hasNext()){
        echo 
    $seraphIterator->next();
        echo 
    "<br>";
    }

    $desians = new ArrayList(5);
    $pronyma = new String("Pronyma");
    $forcystus = new String("Forcystus");
    $rodyle = new String("Rodyle");
    $kvar = new String("Kvar");
    $magnius = new String("Magnius");

    $desians->add($pronyma);
    $desians->add($forcystus);
    $desians->add($rodyle);
    $desians->add($kvar);
    $desians->add($magnius);
    $desianIterator $desians->iterator();

    echo 
    "<br>Cruxis has the following Five Grand Cardinals:<br>";
    while(
    $desianIterator->hasNext()){
        echo 
    $desianIterator->next();
        echo 
    "<br>";
    }

    $desianIterator->rewind();
    echo 
    "The leader of the desian grand cardinals is: ";
    echo 
    $desianIterator->next();
    echo 
    "<br>";

    $cruxis = new ArrayList($desians);
    $cruxis->insertAll(0$seraphim);
    $remiel = new String("Remiel");
    $cruxis->add($remiel);
    $cruxisIterator $cruxis->iterator();
    echo 
    "<br>The following members all belong to cruxis: <br>";
    while(
    $cruxisIterator->hasNext()){
        echo 
    $cruxisIterator->next();
        echo 
    "<br>";
    }

    $deceaced = new ArrayList;
    $deceaced->add($magnius);
    $deceaced->add($kvar);
    $deceaced->add($remiel);
    $deceaced->add($martel);
    $deceacedIterator $deceaced->iterator();
    echo 
    "<br>The following {$deceaced->size()} members are already dead before we visit Tethe'alla: <br>";
    while(
    $deceacedIterator->hasNext()){
        echo 
    $deceacedIterator->next();
        echo 
    "<br>";
    }

    $cruxis->removeAll($deceaced);
    $aliveIterator $cruxis->iterator();
    echo 
    "<br>As a result, only the following Cruxis Members are still alive: <br>";
    while(
    $aliveIterator->hasNext()){
        echo 
    $aliveIterator->next();
        echo 
    "<br>";
    }

    $cruxis->retainAll($desians);
    $aliveIterator $cruxis->iterator();
    echo 
    "<br>The Desian Grand Cardinals still alive are: <br>";
    while(
    $aliveIterator->hasNext()){
        echo 
    $aliveIterator->next();
        echo 
    "<br>";
    }
    ?>
    HashMap: (preview @ http://mysidiarpg.com/site/collection/hashmapdemo.php)
    PHP Code:
    <?php

    require "autoloader.php";

    $mithosKey = new String("Mithos Yggdrasill");
    $martelKey = new String("Martel Yggdrasill");
    $yuanKey = new String("Yuan Ka-fei");
    $kratosKey = new String("Kratos Aurion");
    $remielKey = new String("Remiel");

    $mithosValue = new String("Leader of Cruxis");
    $martelValue = new String("Mithos' Older Sister");
    $yuanValue = new String("Leader of Renegades");
    $kratosValue = new String("One of Four Seraphim");
    $remielValue = new String("Minion of Cruxis");

    $map = new HashMap;
    $map->put($mithosKey$mithosValue);
    $map->put($martelKey$martelValue);
    $map->put($yuanKey$yuanValue);
    $map->put($kratosKey$kratosValue);

    $pronymaKey = new String("Pronyma");
    $forcystusKey = new String("Forcystus");
    $rodyleKey = new String("Rodyle");
    $kvarKey = new String("Kvar");
    $magniusKey = new String("Magnius");

    $pronymaValue = new String("Twilight Pronyma");
    $forcystusValue = new String("Forcystus the Gnashing Gale");
    $rodyleValue = new String("Iron Will Rodyle");
    $kvarValue = new String("Kvar the Fury Tempest ");
    $magniusValue = new String("Magnius the Pyrcoclasm");

    $map2 = new HashMap;
    $map2->put($pronymaKey$pronymaValue);
    $map2->put($forcystusKey$forcystusValue);
    $map2->put($rodyleKey$rodyleValue);
    $map2->put($kvarKey$kvarValue);
    $map2->put($magniusKey$magniusValue);
    $map2->putAll($map);

    $iterator $map2->iterator();
    while(
    $iterator->hasNext()){
        
    $entry $iterator->nextEntry();
        echo 
    "{$entry->getKey()}{$entry->getValue()}<br>";
    }
    ?>

    As you see, these collection classes do behave in astoundingly similar way to Java and C#. The ArrayList plays with an internal fixed sized array(an instance of subclass of SplFixedArray), elements inside ArrayList are ordered by insertion sequence. The HashMap class contains a set of key-value pairs that each key is mapped to a unique value. HashMap is not ordered though, you will have to use LinkedHashMap if you want the elements to be ordered by insertion sequence.

    Note this PHP collections framework is still somewhat different from Java and C#'s. First of all, PHP is not Java, and thus the code has to compensate for the differences and make the best use of what PHP has to offer. Second, PHP does not have inner/anonymous class support, this results in a large number of classes that need dependency injection of their corresponding outer classes. Third, not every class in PHP inherits from Object, which makes type hinting tricky to handle. The naming convention is also quite different, but I guess this is not a problem. But anyway, I am able to find out ways to resolve these problems, and PHP collections framework is ready to be used now!

    One drawback of the project at this stage is that PHP does not allow autoboxing. For this reason, PHP collections framework wont handle primitive data types. Instead, you have to use wrapper objects for primitive types(such as Integer, Float, Boolean and String). There is an Autoboxer class in Utility folder, which will be useful. In future I plan to work on primitive collection adapter classes to work with primitive types, it will be an interesting thing to do.


    So what do you think? I see good potential in my PHP collections framework, while at this stage I am open to any types of constructive criticism. You can download PCF v1.0 from mediafire if you are interested in trying out on your site(at 122kb, its actually quite lightweight). It is already usable at this point, although I will keep improving it by adding new functionality every now and then.

    Download Link:
    http://www.mediafire.com/?58jf3hlmi9cnb3i
    Last edited by Hall of Famer; April 7th, 2013 at 02:38 AM.
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    5
    Rep Power
    0
    Sounds interesting, well done.
  4. #3
  5. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,317
    Rep Power
    7170
    My primary question would be what are the advantages of using this instead of a normal array?
    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Location
    Ithaca
    Posts
    68
    Rep Power
    2
    @ Curtis Delicata:
    Thank you so much for the nice comment, and yeah I will keep working on the project to make it more useful and powerful.

    @ E-oreo:
    The PHP Collections Framework(PCF) is way more object oriented, it is desirable to handle collections of objects. PHP arrays are not objects, and thus lack the functionality of OOP(reference var, object key, iterator methods for instance).

    This framework will be mostly useful for larger projects that need powerful and flexible way of manipulating collections. If your site/framework runs with ORM, chances are you will find it more useful at handling of collection of domain objects than PHP arrays(same reason why Doctrine has an ArrayCollection class to handle Entities rather than use PHP arrays). For very small projects and fansites, such advantages are not evident.
    Last edited by Hall of Famer; April 7th, 2013 at 06:11 PM.
  8. #5
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    Hi,

    no offense, but I think you've not really understood the purpose of a high-level language.

    Do you know why Java has 20 different collection classes, while PHP has just arrays? It's because Java is a (relatively) low-level language designed to use the underlying system very efficiently. Each class is optimized for a very specific purpose, so that the developers can choose the most efficient tool for each task.

    PHP (and Ruby, Python, Perl, ...) is completely different. It's a high-level language designed for quick development and ease of use. It's aimed at humans, not machines. Instead of arrays, ArrayLists, Queues, Stacks and whatever, you simply have arrays with all those features. This means PHP arrays are much less efficient, but they free you from technical decisions and restrictions.

    When you implement all those Java classes in PHP, that's just absurd. The wide range of collection classes is a drawback of a low-level language, it's nothing you want. It's OK in Java, because you get a good performance in return. It's completely useless in PHP, because this won't improve performance in any way. In the end, every class is just a wrapper for a plain PHP array (with a few exceptions).

    So this is like imposing the maximum line length of Fortran on PHP or something.

    Now, it does sometimes make sense to write wrappers for arrays or write more specialize classes. For example, it's rather weird that arrays can have both numeric and string keys, so in an OOP environment, it might be a good idea to have an Array class and a separate Hash class (like many other languages). But you make those distinctions for semantic reasons. The Java classes exist for technical reasons.

    I mean, I'm sure it was a lot of fun to write those classes, and you probably learnt a lot about data types. But this library is not very useful for real-life. Why on earth would I want to write hundreds of lines of boilerplate code and absurdities like new String("...") when I can have the same functionalities in just 10 lines?

    Sorry, but if I wanted to write Java code and torture my eyes with AbstractFactoryObserverSingletons, I'd use Java.

    Don't forget that OOP or programming in general is a tool to solve problems, not a typing exercise or mental masturbation (although that's sometimes interesting, too).

    Comments on this post

    • PaulGer agrees
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Location
    Ithaca
    Posts
    68
    Rep Power
    2
    Well I do agree that for small project there is basically no benefit of using the collections framework, but I also believe it will come in handy with large applications running ORM. These data structures fit well with datamappers and the other domain model patterns. I am already implementing this into my application, its been working well so far.

    Also Yii framework has its own implementation of collections framework, though significantly light-weight compared to mine. Yii is a very good framework, and thus its usage of data structure justifies the point that collections framework can be useful. Compared to Yii's, my collections framework uses SplFixedArray as internal array, so significantly faster than PHP arrays.
    Last edited by Hall of Famer; April 17th, 2013 at 08:47 PM.
  12. #7
  13. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,957
    Rep Power
    1046
    There's nothing wrong with implementing a custom array class and maybe a hash class in addition to that. But going through the Java API and transferring the classes one by one into PHP means misunderstanding their purpose.

    I mean, do you also make an integer library with a Byte, a Smallint, an Int and a Long? Certainly not, because those only make sense in the context of a low-level language that actually has different integer sizes within memory.

    As a concrete example: How does having one class for a queue and one for a stack and one for a linked list help me write my web application? I do not care about stacks, queues, linked lists, vectors and all that other stuff from the computer science class. I wanna make a simple list of things and then do everything you can do with a list: get the first element, remove it, prepend a new element, get the last element, remove it, append a new element, get an element in between, remove it, add a new element at an index etc. I certainly do not want to keep copying the content to different data structures just because each one can only do three of these actions.

    That's the difference between low-level hardware oriented programming and high-level "semantic programming". As a Java programmer, you think in chars, smallints, ints and longs. As a PHP programmer, you just want an integer. The technical implementation of this integer doesn't matter to you (maybe you wanna know the range of possible values, but that's it).

    Like you already said: PHP isn't Java. Trying to turn it into Java won't really help, I believe.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".

IMN logo majestic logo threadwatch logo seochat tools logo