Home
About
Search
🌐
English Română
  • Factory method pattern using PHP 5.3 and late static bindings

    Citește postarea în română

    Jan 24, 2010 Design patterns PHP php5 php5.3
    Share on:

    Factory method design pattern introduced by GoF (Gang of Four) which I’ve talked about in a previous blog, has the base idea of a method that generates objects. Most implementations are “poor”, because they use a lot of hard-coding for the factory (just like me in the previous blog).

    PHP 5.3 offers the possibility of a very interesting implementation using “Late static bindings“.

    The classes from which the objects will be generated are:

     1// abstract base class that will be inherited
     2abstract class Drink {
     3
     4    // ingredients
     5    protected $ingredients;
     6
     7    // public method for producing the drink
     8    abstract public function MakeDrink();
     9}
    10
    11// a child class for tea
    12class Tea_Drink extends Drink {
    13
    14    // ingredients for tea
    15    protected $ingredients = array('tea', 'sugar', 'mink', 'water');
    16
    17    // make tea
    18    public function MakeDrink() {
    19
    20        // make tea
    21    }
    22}
    23
    24// another class for Bloody Mary
    25class BloodyMary_Drink extends Drink {
    26
    27    // ingredients for Bloody Mary
    28    protected $ingredients = array('votka', 'salt', 'tomato juice');
    29
    30    // make Bloody Mary
    31    public function MakeDrink() {
    32
    33        // make BloodyMary
    34
    35    }
    36}
    

    The idea is to have an abstract factory class to extend as simple as possible when creating each new factory class.

    PHP 5

    In PHP 5 the class will look something like this:

     1// abstract Factory class
     2abstract class absFactory {
     3
     4    // name of the base class
     5    static protected $base_class = '';
     6
     7    // factory method
     8    public static function getInstance($type) {
     9
    10        // name of the resulting class
    11        $class_name = $type . '_' . self::$base_class;
    12
    13        // check if class exists
    14        // here you can add an autoloader
    15        if(!class_exists($class_name)) {
    16            throw new Exception( 'Class ' . $class_name . ' not loaded!');
    17        }
    18
    19        // check to see if the class inherits the base class
    20        if(!is_subclass_of($class_name, self::$base_class)) {
    21            throw new Exception(
    22                'Class ' . $class_name . ' is not a child of ' . self::$base_class
    23            );
    24        }
    25
    26        // new object
    27        return new $class_name;
    28
    29    }
    30
    31}
    

    Because the getInstance() method is static the property will be static too.

    If we try:

     1class DrinkFactory extends absFactory {
     2
     3    static protected $base_class = 'Drink';
     4}
     5
     6try {
     7
     8    $obj = DrinkFactory::getInstance('Tea');
     9
    10} catch (Exception $e) {
    11
    12    echo $e->getMessage();
    13}
    

    The output will be:

    1Class Tea_ not loaded!
    

    Because of the “self”, we can’t just call the method using the child class because the value of $base_class will be “” and not “Drink”, we must overwrite the getInstance() method. Which is quite “complicated”.

    A working version in PHP 5 will be:

     1class DrinkFactory extends absFactory {
     2
     3    public static function getInstance($type) {
     4
     5        self::$base_class = 'Drink';
     6
     7        // factory method of the base factory class
     8        parent::getInstance($type);
     9
    10    }
    11
    12}
    13
    14try {
    15
    16    $obj = DrinkFactory::getInstance('Tea');
    17
    18} catch (Exception $e) {
    19
    20    echo $e->getMessage();
    21}
    

    But is not exactly “elegant”.

    PHP 5.3

    Here we have “Late static bindings”, which is basically introducing the work “static”.

    The base factory class will look something like this:

     1// abstract Factory class
     2abstract class absFactory {
     3
     4    // name of the base class
     5    static protected $base_class = '';
     6
     7    // factory method
     8    public static function getInstance($type) {
     9
    10        // name of the resulting class
    11        $class_name = $type . '_' . static::$base_class;
    12
    13        // check if class exists
    14        // here you can add an autoloader
    15        if(!class_exists($class_name)) {
    16            throw new Exception( 'Class ' . $class_name . ' not loaded!');
    17        }
    18
    19        // check to see if the class inherits the base class
    20        if(!is_subclass_of($class_name, static::$base_class)) {
    21            throw new Exception(
    22                'Class ' . $class_name . ' is not a child of ' . static::$base_class
    23            );
    24        }
    25
    26        // new object
    27        return new $class_name;
    28
    29    }
    30
    31}
    

    A change so small allows us to create a much “nicer” factory class:

     1class DrinkFactory extends absFactory {
     2
     3     static protected $base_class = 'Drink';
     4
     5}
     6
     7try {
     8
     9    $obj = DrinkFactory::getInstance('Tea');
    10
    11} catch (Exception $e) {
    12
    13    echo $e->getMessage();
    14}
    

    Basically in this version only the relevant property in this context is overwritten.

  • Factory method design patten in PHP

    Citește postarea în română

    Jan 23, 2010 Design patterns PHP
    Share on:

    An creational design pattern, which represents an solution for generation objects without specifying the class name. Virtually all methods that generate objects are particular implementations of the Factory Method pattern.

    Motivation:

    A motivation for this choice is that the creation of the object is delegated to the factory method.

    Diagram:

    factory method pattern

    Implementation:
    The classes that generates the objects, the common class to extend and the class with the factory method:

      1// the common class to be extended
      2abstract class OutputBase {
      3     // output the necessary headers
      4     abstract public function header();
      5
      6     // resulting body
      7     abstract public function body($data);
      8
      9}
     10
     11// class for XML ouput
     12class XMLOutput extends OutputBase {
     13
     14     // output XML header
     15     public function header() {
     16          header('content-type: text/xml');
     17     }
     18
     19     // xml document
     20     public function body($data) {
     21          $res = '';
     22
     23          $res .= '';
     24
     25          foreach ($data as $root => $item) {
     26
     27               $res .= '';
     28
     29               foreach ($item as $key => $val) {
     30                    $res .= '<'.$key.'>'.$val.'';
     31               }
     32
     33               $res .= '';
     34          }
     35
     36          $res .= '';
     37
     38          return $res;
     39
     40     }
     41
     42}
     43
     44// class for CSV output
     45class CSVOutput extends OutputBase {
     46
     47     // output CSV header
     48     public function header() {
     49          header("Content-type: text/plain");
     50     }
     51
     52     // CSV body
     53     public function body($data) {
     54          $res = '';
     55
     56          $keys = array_keys($data[0]);
     57
     58          foreach ($keys as $key) {
     59               $res .= '"'.$key.'";';
     60          }
     61          $res .= "\r\n";
     62
     63          foreach ($data as $item) {
     64               foreach ($item as $val) {
     65                    $res .= '"'.$val.'";';
     66               }
     67
     68               $res .= "\r\n";
     69          }
     70
     71          return $res;
     72     }
     73}
     74
     75// the factory method class
     76// is abstract so it wont be instantiated
     77abstract class OutputFactory {
     78
     79     // constant for XML type
     80     const XML = 1;
     81
     82     // constant for CSV type
     83     const CSV = 2;
     84
     85     // static factory method
     86     public static function getInstance($type) {
     87          // depending which constant was received as a parameter
     88          // one of the objects will be returned
     89          switch ($type) {
     90               case self::XML :
     91                    return new XMLOutput();
     92               break;
     93
     94               case self::CSV :
     95                    return new CSVOutput();
     96               break;
     97          }
     98
     99          // if the value received as a parameter is not one of the constants
    100          // an exception will be thrown
    101          throw new Exception('Invalid class type!');
    102     }
    103
    104}
    

    Example:

     1// the data
     2$data = array(
     3               array(
     4                    'a' => 1,
     5                    'b' => 2,
     6                    'c' => 3
     7                    ),
     8               array(
     9                    'a' => 4,
    10                    'b' => 5,
    11                    'c' => 6
    12                    )
    13          );
    14
    15// try-catch block in case of an exception
    16try {
    17     // generation the object
    18     $obj = OutputFactory::getInstance(OutputFactory::XML);
    19
    20     // output headers
    21     $obj->header();
    22
    23     // display body
    24     echo $obj->body($data);
    25
    26} catch (Exception $e) {
    27
    28     $e->getMessage();
    29
    30}
    
  • Another year has passed and PHP 6 is still not here…

    Citește postarea în română

    Jan 13, 2010 MySQL php5.3 php6
    Share on:

    Another year has passed and PHP 6 is still not here…

    But that’s not exactly news, is the 4-th year when this long awaited version is not released. Not for nothing is called the most awaited version.

    But overall it was a good year for the community, even though we still don’t have native Unicode in a stable version now we have all other awaited features in PHP 5.3, which will probably need another few years to become used on a large scale.

    Even though everyone was expecting last year for Oracle to enter in full force on medium and small database market by purchasing Sun, enlarging it’s already well established  portfolio on the enterprise market. It seems that it was not to be, CE is still analyzing the deal.

    However MySQL is not what it used to be 5-6 years ago, when nobody dared to use it for enterprise products. This days MySQL is a product ready to be used in both small and large products that require a lot of scalability.

    But back to the year that just ended, it was a full year, even with this economic crises.

  • CodeIgniter 1.7 Packt Publishing – Book review part 1

    Citește postarea în română

    Dec 9, 2009 CodeIgniter PHP
    Share on:

    1847199488

    CodeIgniter is an open-source PHP framework, build for RAD development. This framework is continuously growing in popularity, probably especially since people realized that is much easier to use an open-source framework instead of developing an internal one, but that’s another story. The CodeIgniter 1.7 book from PacktPublishing, written by Jose Argudo Blanco and David Upton is building a big picture about the CodeIgniter 1.7 framework, as an addition to the reference manual.

    After all every respectable framework has an detailed reference, with usability examples, more or less comprehensible. When it comes to learning an framework (and not only), an reference is usually not the best place to start from, because is hard to get the big picture when you can only receive atomic answers. That’s why we buy books this days, to have a general image with problems and solutions. And this is where the CodeIgniter 1.7 book comes in.

    Initially, when I’ve seen that the title has the version number of the analyzed framework I was a little pessimistic, because usually when you buy a book you don’t want it to be tight up to particular version, isn’t it? Well, not exactly… I had a similar issue with Zend Framework, most books use “older versions”  (ex: 1.5-1.6) and I wanted to see an approach using the new features from version 1.8 or greater. After all when you start learning something you usually want the latest version of the framework or what ever it is that you are learning, and when new features appear it will be much easier to simply look then in the reference guide since you already know the basics.

    This book seams to start from the beginners level and progressively describe both basic elements as well as the most common problems the user may encounter when developing apps using the CodeIgniter framework.  The sample chapter, looks pretty well structured and easy to understand, and from the table of contents it seams to approach all the important subjects. With the hope that the rest of the book will be just as well structured (I’m actually judging a book by the cover?) and a second part to this review will follow I can’t barely wait for the book.

    To be continued…

  • Adobe AIR

    Citește postarea în română

    Nov 6, 2009 Adobe AIR JavaScript soap Webkit zend framework
    Share on:

    Last week I was supposed to create a little project. Requirements were short: interoperability.Given the fact that I’ve never used Adobe AIR before, I thought it was a good opportunity to try it.

    The result was a small project management app. For the server-size I’ve used PHP + SOAP + Zend Framework, and for the client I’ve used Adobe AIR with JavaScript.

    I’ve created the server in a few lines:

     1<?php
     2// autoload class for Zend Framework
     3include 'Zend/Loader/Autoloader.php';
     4
     5// class that deals with SOAP requests
     6include 'SOAP.class.php';
     7
     8// initialize autloader
     9Zend_Loader_Autoloader::getInstance();
    10
    11// if it's a request for the WSDL descriptor file
    12if(isset($_GET['wsdl'])) {
    13 $autodiscover = new Zend_Soap_AutoDiscover();
    14 $autodiscover->setClass('test');
    15 $autodiscover->handle();
    16// if it's a SOAP request
    17} else {
    18 $soap = new Zend_Soap_Server("http://localhost/soap/index.php?wsdl");
    19 $soap->setClass('test');
    20 $soap->handle();
    21}
    22
    23?>
    

    The descriptor is build automatically using PHP Documenter type comments from the class that handles SOAP requests, if this case it’s named “test”.

    This was the easy part so I’ve moved on to the Adobe AIR client following this simple steps:

    • Download and install Aptana Studio
    • Install Adobe AIR plug-in
    • New project -> Adobe AIR
    • and voila! Coding can begin!

    Adobe AIR is using for a JavaScript engine Webkit. Sounds familiar? Webkit is used by Safari and Google Chrome. So the JavaScript code should only be compatible with Webkit!

    Of course there is a “but” and a plus. The “but” is that there are some restrictions, for instance “eval” can only be used to decode JSON, and the text introduced directly in an element (as text) can not be executed:

    1div.innerHTML = "<a onclick=\"alert('ceva')\" href=\"#\">click</a>";
    

    This link will get to the element by will not run anything on “onclick” because the parameter was send as text.

    This was a pretty big disadvantage for me, but I’ve managed to figure out an alternative by building HTML elements using DOM and adding events using addEventListener.

    Briefly Adobe AIR is using this formula:

    1Adobe AIR = (Webkit)Web Development - security + air framework.
    

    It seems very easy for a Web Developer to develop desktop apps with Adobe AIR.

    Of course is not very fast and it’s not looking like a good idea for complex apps. But if your thinking about medium and small apps, if I had to choose between Adobe AIR and PHP GTK for instance, the first option seems a lot more viable and easy to use!

    In the end the project was ready in less then 3 days and the graphics were gorgeous! It didn’t even look like it was build using only HTML and JavaScript!

    • ««
    • «
    • 14
    • 15
    • 16
    • 17
    • 18
    • »
    • »»

Claudiu Perșoiu

Programming, technology and more
Read More

Recent Posts

  • 30 years of PHP
  • HTTPS certificate monitoring in Home Assistant
  • Adding a slider to Tasmota using BerryScript
  • The future proof project
  • Docker inside wsl2
  • Moving away from Wordpress
  • Custom path for Composer cache
  • Magento2 and the ugly truth

PHP 50 MISCELLANEOUS 47 JAVASCRIPT 14 MAGENTO 7 MYSQL 7 BROWSERS 6 DESIGN PATTERNS 5 HOME AUTOMATION 3 LINUX-UNIX 2 WEB STUFF 2 GO 1

PHP 36 JAVASCRIPT 15 PHP5.3 11 MAGENTO 7 PHP6 7 MYSQL 6 PHP5.4 6 ZCE 6 CERTIFICARE 5 CERTIFICATION 5 CLOSURES 4 DESIGN PATTERNS 4 HACK 4 ANDROID 3
All tags
3D1 ADOBE AIR2 ANDROID3 ANGULAR1 ANONYMOUS FUNCTIONS3 BERRYSCRIPT1 BOOK1 BROWSER2 CARTE1 CERTIFICARE5 CERTIFICATION5 CERTIFIED1 CERTIFIED DEVELOPER1 CHALLENGE1 CHM1 CLASS1 CLI2 CLOSURES4 CODE QUALITY1 CODEIGNITER3 COFFEESCRIPT1 COLLECTIONS1 COMPOSER1 CSS1 DEBUG1 DESIGN PATTERNS4 DEVELOPER1 DEVELOPMENT TIME1 DOCKER2 DOCKER-COMPOSE1 DOUGLAS CROCKFORD2 ELEPHPANT2 FACEBOOK2 FFI1 FINALLY1 FIREFOX3 GAMES1 GENERATOR1 GO1 GOOGLE1 GOOGLE CHROME1 GOOGLE MAPS1 HACK4 HOMEASSISTANT3 HTML2 HTML HELP WORKSHOP1 HTML51 HUG1 HUGO1 INFORMATION_SCHEMA1 INI1 INTERNET EXPLORER3 IPV41 IPV61 ITERATOR2 JAVASCRIPT15 JQUERY1 LAMBDA1 LINUX1 MAGENTO7 MAGENTO22 MAP1 MINESWEEPER1 MOTIVATION1 MYSQL6 NGINX1 NODE.JS2 NOSQL1 OBSERVER3 OBSERVER PATTERN1 OOP1 OPERA1 OPTIMIZATION1 ORACLE1 PAGESPEED1 PAIR1 PARSE_INI_FILE1 PHONEGAP2 PHP36 PHP ELEPHANT2 PHP FOR ANDROID1 PHP-GTK1 PHP42 PHP53 PHP5.311 PHP5.46 PHP5.53 PHP5.61 PHP67 PHP7.41 PROGRAMMING1 REVIEW1 ROMANIAN STEMMER2 SAFARY1 SCALAR TYPE HINTING1 SCHEME1 SET1 SHOPPING CART PRICE RULE1 SINGLETON1 SOAP1 SPL2 SQLITE1 SSH1 STACK TRACE1 STDERR1 STDIN1 STDOUT1 SUN1 SYMFONY2 TASMOTA1 TEST TO SPEECH1 TITANIUM2 TRAITS1 TTS1 UBUNTU1 UNICODE2 UTF-82 VECTOR1 WEBKIT1 WINBINDER1 WINDOWS2 WORDPRESS1 WSL21 YAHOO3 YAHOO MAPS1 YAHOO OPEN HACK1 YSLOW1 YUI1 ZCE6 ZCE5.31 ZEND3 ZEND FRAMEWORK3
[A~Z][0~9]

Copyright © 2008 - 2025 CLAUDIU PERȘOIU'S BLOG. All Rights Reserved