Blog

  • ActiveRecord PHP implementation Part I

    By Nuno Mariz, on 6 January 2006 @ 18:09
    ActiveRecord UML
    This is the first part of an attempt to implement the ActiveRecord design pattern in PHP. This first implementation is very simple but will open doors for more advanced stuff, like foreign keys mapping(automatic or manually) or integration with Model, View and Controller components, in this case with the generation of PHP classes or objects. Approach: A row in a database table or view is wrapped into a class, thus an object instance is tied to a single row in the database. Imagine this table(person):
    +-------------+---------------------+
    | Field       | Type                |
    +-------------+---------------------+
    | id          | bigint(20) unsigned |
    | name        | varchar(100)        |
    | email       | varchar(150)        |
    | last_update | datetime            |
    +-------------+---------------------+
    
    With this records:
    +----+----------+---------------+---------------------+
    | id | name     | email         | last_update         |
    +----+----------+---------------+---------------------+
    |  1 | Nuno     | nuno@xxx.xxx  | 2005-11-06 20:39:08 |
    +----+----------+---------------+---------------------+
    |  2 | Marta    | marta@xxx.xxx | 2005-11-06 20:39:08 |
    +----+----------+---------------+---------------------+
    |  3 | Pedro    | joao@xxx.xxx  | 2005-11-06 20:39:08 |
    +----+----------+---------------+---------------------+
    
    You don't have to define any table structure, just extend de ActiveRecord class and call the parent __construct() method with the table name :
    include_once 'class.ActiveRecord.php';
    
    class Person extends ActiveRecord {
        public function __construct() {
            parent::__construct('person');
        }
    }
    
    To return all rows in the table:
    $persons = new Person();
    
    /**
     * This will print all records
     * $persons->findAll() will return a Recordset
     */
    foreach($persons->findAll() as $person) {
        echo 'id: '.$person->id;
        echo 'name: '.$person->name;
        echo 'email: '.$person->email;
        echo 'last update: '.$person->last_update;
    }
    
    /**
     * Alternatively you can 'walk' the Recordset
     * with next(), prev(), etc. because Recordset
     * implements the Iterator interface
     */
    
    Insert a record:
    $person = new Person();
    $person->name = 'Julia';
    $person->email = 'julia@xxx.xxx';
    $person->insert();
    
    Update a record:
    $personId = $_POST['id'];
    $person = new Person();
    $person->id = $personId;
    $person->name = 'Nuno Mariz';
    $person->update();
    
    UPDATE: With the Pádraic Brady tip for merging the insert() and update() methods to only one save() method, now is possible to:
    // insert
    $person = new Person();
    $person->name = 'Nuno Mariz';
    $person->save();
    
    // or update
    $personId = $_POST['id'];
    $person = new Person();
    $person->find($personId);
    $person->name = 'Nuno Mariz';
    $person->save();
    
    You can view the UML for the implementation. See you in part II...
  • Ruby on Rails first try

    By Nuno Mariz, on 15 December 2005 @ 11:38
    Ruby on Rails
    For those who are trying to install Ruby on Rails on Debian(in my case 3.1 STABLE), you will notice that your application will show a blank page and the following error on the WEBrick web server in dev/development.log:
     
    MissingSourceFile (no such file to load -- irb):
    (...)
    
    You must install the following packages:
    apt-get install ruby1.8-dev
    apt-get install irb
    apt-get install libncurses5-dev libreadline5-dev
    
  • Strong growth for Debian

    By Nuno Mariz, on 7 December 2005 @ 14:40
    Debian -- The Universal Operating System
    According to Netcraft, the non-commercial distributions are growing faster than the commercial Linux distributions. In my opinion this is not a big surprise, but with the major companies aquiring some linux distributions like Novell with SUSE, the companies which have partnerships with Novell or Redhat will maintain or migrate for these commercial linux distributions.

    Debian is currently the fastest growing Linux distribution for web servers, with more than 1.2 million active sites in December. Debian 3.1 was declared stable in July and it appears that both the anticipation of this release becoming stable, and the release itself, have generated new interest in Debian, after some years where it had lagged behind its more active rivals. This growth is particularly noticeable at some of the larger central European hosting locations, including Komplex, Lycos Europe, Proxad and Deutsche Telecom.
  • Zend Framework Webcast

    By Nuno Mariz, on 5 December 2005 @ 21:43
    Zend Technologies
    php|architect has posted the recorded version of their Zend Framework webcast on their site. I must say is quite impressive. I've been developing a new framework to take advantage of the new features of PHP5. Right now is quite mature and is in prodution, but lacks of some features. One of the features that is missing is the ActiveRecord that Zend will implement in their new framework. Quite curious is the ZMail, have almost the same API of my Mailer class. One of the aspects that im also curious is the ZForms, right now in my framework is quite flexible. I can extend my FormManager class and add the elements that i need, like this:
    include_once 'class.FormManager.php';
    
    class FormLogin extends FormManager {
      public function __construct() {
        /*
         * Calling the parent
         * Usage::
         * parent::__construct($name,
         *                     $action = null,
         *                     $method = null,
         *                     $enctype = null,
         *                     $extra = null);
         */
        parent::__construct('FormLogin', null, 'POST', null, null);
      }
    
      // Must implement this method  
      public function initElements() {
        /*
         * Adding an Hidden Element
         * Usage:
         * $this->addHiddenElement($name, $value);
         */
        $this->addHiddenElement('module', 'Authentication');
        $this->addHiddenElement('action', 'login');
    
         /*
         * Adding an Element
         * Usage:
         * $this->addElement($type, $name, $label, $options);
         */
        $usernameOptions = array(...)
        $this->addElement('text', 
                          'username',
                          'Username',
                          $usernameOptions);
    
         /*
         * Adding a Validator
         * Usage:
         * $this->addValidator($elementName, $validatorObject);
         */
        $this->addValidator('username',
                            new RequiredValidator());
        $this->addValidator('username',
                            new MaxLengthValidator(array('length'=>15)));
    
        $passwordOptions = array(...)
        $this->addElement('password',
                          'password', 
                          'Password',
                          $usernameOptions);
    
        $loginOptions = array(...);
        $this->addElement('submit', 'login', 'Login', $loginOptions);
      }
    }
    
    $form = new FormLogin();
    $form->render(); // render HTML form
    echo $form->getFormStart();
    // show the Username label
    echo $form->getElementLabel('username'); 
    // show the Username imput
    echo $form->getElementInput('username'); 
    // show the Password label
    echo $form->getElementLabel('password'); 
    // show the Password input
    echo $form->getElementInput('password'); 
    // show the Login submit button
    echo $form->getElementInput('login'); // show the Login submit button
    echo $form->getFormEnd();
    
    Another way is to load the XML configuration for the form:
    include_once 'class.XMLFormManager.php';
    
    $form = new XMLFormManager('FormLogin.xml');
    $form->render(); // render HTML form
    echo $form->getFormStart();
    echo $form->getElementLabel('username'); // show the Username label
    echo $form->getElementInput('username'); // show the Username imput
    echo $form->getElementLabel('password'); // show the Password label
    echo $form->getElementInput('password'); // show the Password input
    echo $form->getElementInput('login'); // show the Login submit button
    echo $form->getFormEnd();
    
    In the XML way is quicker, i have a web application to generate the XML automatically. I can create or load XML forms and edit with an interface. I can bind elements with database table fields, add and configure validators, etc. Recently i've improved the package to support the binding of an element with a database table field, the syntax is similary but with 2 more parameters in the addElement() method.
  • Sun Announces Support for PostgreSQL

    By Nuno Mariz, on 18 November 2005 @ 11:20
    Sun Microsystems
    The server and software company said Thursday that it will integrate PostgreSQL into its Solaris operating system, and will begin offering support services to business customers running the software.

    At a press conference here, company executives said Sun engineers will participate in the PostgreSQL open-source project to tune the database for Solaris and beef up its high-end capabilities.


    By cnet.com
  • PHP Collaboration Project

    By Nuno Mariz, on 20 October 2005 @ 18:08
    Zend Technologies
    WOW. Im already anxious to see this working. One thing that think that is missing in PHP, is the existence of an web application framework or an Application Server, which standardizes the way PHP applications are built.
    What is the PHP Collaboration Project?
    The PHP Collaboration Project is an open source initiative through which the PHP community and partners will create an industrial-grade PHP Web application development and deployment environment...


    Zend PHP Framework
    A Web application framework which standardizes the way PHP applications are built. The Zend PHP Framework accelerates and improves the development and deployment of mission-critical PHP Web applications.
    By Joel's Corner
  • iMic for my Mac mini

    By Nuno Mariz, on 21 September 2005 @ 15:27
    iMic
    I think that is very weird that Mac mini doesn't have a mic or a simple line-in interface, i had to wait for 15 days and pay for the iMic 53 €. For those who doesn't know what it is:
    The iMic universal audio adapter is a USB device that adds stereo input and output to your Mac or PC. Connect virtually any microphone or sound input device to your iBook, PowerBook, PowerMac or other Mac or PC with a USB port. Yes, iMic supports both Mic level and line level input. It also supports line level output for connecting speakers or an external recording device.
  • Apple's G5 versus x86, Mac OS X versus Linux

    By Nuno Mariz, on 2 September 2005 @ 14:59
    Mac OS X
    I've found an interesting article comparing Apple's G5 versus x86 and Mac OS X versus Linux. Basically resumes to this:
    Workstation, yes; Server, no.

    The G5 is a gigantic improvement over the previous CPU in the PowerMac, the G4e. The G5 is one of the most superscalar CPUs ever, and has all the characteristics that could give Apple the edge, especially now that the clock speed race between AMD and Intel is over. However, there is still a lot of work to be done.

    The server performance of the Apple platform is, however, catastrophic. When we asked Apple for a reaction, they told us that some database vendors, Sybase and Oracle, have found a way around the threading problems. We'll try Sybase later, but frankly, we are very sceptical. The whole "multi-threaded Mach microkernel trapped inside a monolithic FreeBSD cocoon with several threading wrappers and coarse-grained threading access to the kernel", with a "backwards compatibility" millstone around its neck sounds like a bad fusion recipe for performance.

    Workstation apps will hardly mind, but the performance of server applications depends greatly on the threading, signalling and locking engine. I am no operating system expert, but with the data that we have today, I think that a PowerPC optimised Linux such as Yellow Dog is a better idea for the Xserve than Mac OS X server.
    No more mysteries:
    Apple's G5 versus x86, Mac OS X versus Linux Part One, Part Two
  • "Submitting a bug to PHP" - The novel

    By Nuno Mariz, on 29 August 2005 @ 15:54
    This is my first(and the last) time of an attempt to submit a bug to PHP. I am using PDO in PHP5 and my Apache gets a "Segmentation Fault" when I execute an invalid SQL statement.
    [26 Aug 8:02pm CEST] nmariz at estadias dot com
    
    Description:
    ------------
    Segmentation fault in Apache when executing an invalid SQL.
    
    apache error.log:
    
    [Fri Aug 26 18:10:42 2005] [notice] child pid 26519 exit signal
    Segmentation fault (11)
    
    Actual result:
    --------------
    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 1079565216 (LWP 28567)]
    0x40865cf5 in _efree (ptr=0x83bbf58) at
    /root/software/php-5.1.0RC1/Zend/zend_alloc.c:302
    302             REMOVE_POINTER_FROM_LIST(p);
    (gdb) bt
    #0  0x40865cf5 in _efree (ptr=0x83bbf58) at
    /root/software/php-5.1.0RC1/Zend/zend_alloc.c:302
    #1  0x40727109 in pdo_mysql_stmt_dtor (stmt=0x0, tsrm_ls=0x817ecf8) at
    /root/software/php-5.1.0RC1/ext/pdo_mysql/mysql_statement.c:45
    
    (...)
    
    [26 Aug 9:29pm CEST] xxx@php.net
    
    Thank you for this bug report. To properly diagnose the problem, we
    need a short but complete example script to be able to reproduce
    this bug ourselves. 
    
    A proper reproducing script starts with < ?php and ends with ?>,
    is max. 10-20 lines long and does not require any external 
    resources such as databases, etc.
    
    If possible, make the script source available online and provide
    an URL to it here. Try to avoid embedding huge scripts into the report.
    
    [29 Aug 10:42am CEST] nmariz at estadias dot com
    
    Segmentation fault when executing an invalid SQL statement:
    
    < ?php
    (...)
    // invalid sql statement
    $query = 'SELECT id name,text FROM modules';
    $stmt = $this->dbconn->query($query);
    $result = $stmt->fetchAll();
    $stmt = null;
    return $result
    (...)
    ?>
    
    [29 Aug 1:24pm CEST] xxx@php.net
    
    What part in "a short but complete example script" did you not
    understand?
    
    
    [29 Aug 5:00pm CEST] nmariz at estadias dot com
    
    What part in "Segmentation fault when executing an invalid
    SQL(_____ANY_____) statement" did you not understand?
    I think that you don't need more code to understand what i mean.
    
    [29 Aug 5:07pm CEST] xxx@php.net
    
    I think you don't understand that I am very very lazy.
    And that your problem _might_ be somewhere ELSE than in the query part.
    So either give the full code or go away.
    
    Unbelievable!
    UPDATE: After i had submitted the code that he asked, the guy simply erased all logs and submitted this:
    [29 Aug 11:34pm CEST] xxx@php.net
    
    Thank you for this bug report. To properly diagnose the problem, we
    need a short but complete example script to be able to reproduce
    this bug ourselves. 
    
    A proper reproducing script starts with < ?php and ends with ?>,
    is max. 10-20 lines long and does not require any external 
    resources such as databases, etc.
    
    If possible, make the script source available online and provide
    an URL to it here. Try to avoid embedding huge scripts into the report.
    
    You can see the log in here.
  • Django: Another "Rails" Web Framework

    By Nuno Mariz, on 18 July 2005 @ 11:51
    The Rails hype continues:
    Django for Python is the most recently announced of what is becoming a long line of web frameworks inspired by Ruby on Rails. Others that have popped up include MonoRail for .NET & Mono, Subway for Python, Trails for Java, Catalyst and Maypole for Perl. In the context of all these rails derivatives, this article on "Could Rails have been built without Ruby?" is an interesting read. [source]
    For PHP we have also cake and biscuit.