PhpMyAdmin: Keeping the session alive

Here we will see how to configure PhpMyAdmin to avoid the “login again” request when the session expires.

If the “login again” message is bothering you because the session has expired after 30 minutes (1800 seconds), which is a really short time :-), we can follow the next steps to keep the session alive.

The first step is to edit the configuration file (config.inc.php):

1
user@unix:~$ gedit /path/to/your/phpmyadmin/config.inc.php

And replace the below line:

1
$cfg['Servers'][$i]['auth_type'] = 'cookie';

For this:

1
$cfg['Servers'][$i]['auth_type'] = 'http';

And, at the end of the file we should add:

1
$cfg['LoginCookieValidity'] = 86400;

That’s it, we should save the modifications and enter PhpMyAdmin again.

PHP: Implementing MVC design pattern

Based in the symfony docs we will try to summarize the implementation of MVC with PHP.

In a previous post we explained the MVC design pattern, and now we’re going to see how to implement it in PHP.

To implement this pattern and try to understand it a little more we’ll see how to transform a basic PHP application in a MVC app. In this case, we’ll build a posts list in a blog. To show a post list from the database in the PHP spaghetti way the script would looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
// Connecting, selecting database
$link = mysql_connect('localhost', 'myuser', 'mypassword');
mysql_select_db('blog_db', $link);
 
// Performing SQL query
$result = mysql_query('SELECT date, title FROM post', $link);
?>

<html>
    <head>
        <title>List of Posts</title>
    </head>
    <body>
        <h1>List of Posts</h1>
        <table>
        <tr><th>Date</th><th>Title</th></tr>
<?php
// Printing results in HTML
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
    echo "<tr>";
    printf("<td> %s </td>", $row['date']);
    printf("<td> %s </td>", $row['title']);
    echo "";
}
?>

        </table>
    </body>
</html>
<?php
// Closing connection
mysql_close($link);
?>

The above script is easy to write, fast to execute, but hard to maintain; some of the trouble we can find is the absence of errors checking (what happen if the db connection fails?), the HTML and the PHP code are all mixed and the script is tied to the MySQL database.

Splitting the presentation out

The echo and printf calls make the code hard to read. To edit the HTML is a pain in the above script, so lets split the code in two sides. First, the PHP code with all the business logic in a Controller (index.php):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
// Connecting, selecting database
$link = mysql_connect('localhost', 'myuser', 'mypassword');
mysql_select_db('blog_db', $link);
 
// Performing SQL query
$result = mysql_query('SELECT date, title FROM post', $link);
 
// Filling up the array for the view
$posts = array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
    $posts[] = $row;
}
 
// Closing connection
mysql_close($link);
 
// Requiring the view
require('view.php');

And, the View script (view.php):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html>
    <head>
        <title>List of Posts</title>
    </head>
    <body>
        <h1>List of Posts</h1>
        <table>
            <tr><th>Date</th><th>Title</th></tr>
<?php
foreach ($posts as $post):
?>
            <tr>
                <td>
                    <?php echo $post['date']; ?>
                </td>
                <td>
                    <?php echo $post['title']; ?>
                </td>
            </tr>
<?php
endforeach;
?>

        </table>
    </body>

To determine if the view is clean enough, a good rule is to have the minimum amount of PHP code in a way that the view could be understand it by a designer without PHP knowledge. The most common and proper PHP syntax in the view are echo, if/endif and foreach/endforeach. Also, there should not be PHP code printing HTML tags.

Hence, all the logic is moved into the controller (containing only PHP, with no HTML)
Por ende, toda la lógica es movida al controlador, y contiene solo código PHP, sin HTML. Como algo importante, deberías imaginar que el mismo controlador debería poder ser usado para diferentes presentaciones (vistas), tales como paginas HTML, archivos PDF, o en una estructura XML.

Isolating the data manipulation

Most of the controller code is dedicated to the data manipulation. But, what happen if we need to list the post for another controller, for instance, one which has a feed RSS output, or if we want to change the data model, like change the table name from post to weblog_post, or we have to change the database engine from MySQL to PostgreSQL. To be able to do all those things we have to remove the data manipulation from the controller and put that logic in the model (model.php):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
function getAllPosts()
{
    // Connecting, selecting database
    $link = mysql_connect('localhost', 'myuser', 'mypassword');
    mysql_select_db('blog_db', $link);
 
    // Performing SQL query
    $result = mysql_query('SELECT date, title FROM post', $link);
 
    // Filling up the array
    $posts = array();
    while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
        $posts[] = $row;
    }
 
    // Closing connection
    mysql_close($link);
 
    return $posts;
}

And modifying the controller (index.php) to include the model:

1
2
3
4
5
6
7
8
9
<?php
// Requiring the model
require_once('model.php');
 
// Retrieving the list of posts
$posts = getAllPosts();
 
// Requiring the view
require('view.php');

In this way we have a really readable controller since if unique task is to get the data from the model and pass it to the view. In more complex apps, the controller also handles the request, the user session, the authentication and much more functionalities.

Source: Symfony documentation

PHP 5.3.3. released

The PHP 5.3.3 was released a few days ago.

The PHP core team has announced the 5.3.3 availability. This release has focused on improve security and stability issues with more than 100 fixed bugs, most of them related to security issues.

Previous versions incompatibility
For previous version than 5.3.3 there is a big incompatibility. The methods with the same name as the class name used by the namespace are not anymore considered as the class constructor. This change does not affect the classes those do not use namespaces.

1
2
3
4
5
6
7
8
9
10
<?php
namespace Foo;
class Bar
{
    public function Bar()
    {
        // Act as constructor in PHP 5.3.0-5.3.2
        // Act as a regular method in PHP 5.3.3
    }
}

This change does not have impact in migrations from PHP 5.2.x, due to namespaces were introduced from PHP 5.3.0.

PHP for Android

A few days ago was released a project to build applications based on Android with PHP.

This project allows us to build apps for Google’s operating system with the most popular scripting language (PHP). With this project the PHP developers will be able to run PHP in every device based on Android.

The phpforandroid.net project was build over the Android Scripting Environemnt (ASE) which was renamed to Scripting Layer for Android (SL4A), which allows developers to run scripting languages like PHP and Phyton.

The project is at its beginning and for sure it will evolve with the time and the community’s help. I was playing a little bit and it works perfectly so far.

The project also has a really good documentation and we can use an Android emulator to test out apps.

Here there is a video that shows how phpforandroid works:

How to send emails with Symfony 1.3 / 1.4

In this post we will see how to send emails with Swift Mailer through Symfony.

As we mentioned in an earlier post, Symfony comes with an already integrated mailer library. And, send an email is as simple as we can see below:

1
2
3
4
<?php
public function executeSendEmail() {
    $this->getMailer()->composeAndSend('from@example.com', 'to@example.com', 'Subject', 'Body');
}

Or, you can chose for compose the message and then send it with the Send() method:

1
2
3
4
5
<?php
public function executeSendEmail() {
    $this->getMailer()->compose('from@example.com', 'to@example.com', 'Subject', 'Body');
    $this->getMailer()->send();
}

Furthermore, if we need to add a little more of complexity like attach a file, it is as simple as we can see below:

1
2
3
4
5
6
<?php
public function executeSendEmail() {
    $this->getMailer()->compose('from@example.com', 'to@example.com', 'Subject', 'Body')
        ->attach(Swift_Attachment::fromPath('/path/to/a/file.zip'));
    $this->getMailer()->send();
}

As we can observe in the previously used methods Symfony handles mailing issues with a Mailer object, which is got it with the getMailer() method, already ready to use in the controller due to that the mailer object already is part of the Symfony’s core.

Configuration

By default, the send() method tries to use the local SMTP server to send the message, but, of course, as a lot of Symfony stuff this is totally configurable.

As we mentioned previously the Mailer object is part of the Symfony’s core. These objects are automatically built, configured and handled them by the framework. All of the core objects are configurable by the factories.yml file.

The default configuration looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mailer:
  class: sfMailer
  param:
    logging: %SF_LOGGING_ENABLED%
    charset: %SF_CHARSET%
    delivery_strategy: realtime
    transport:
      class: Swift_SmtpTransport
      param:
        host: localhost
        port: 25
        encryption: ~
        username: ~
        password: ~

When a new application is built, the factories.yml file overwrites the default configuration with some sensitive environments variables:

1
2
3
4
5
6
7
8
9
test:
  mailer:
    param:
      delivery_strategy: none

dev:
  mailer:
    param:
      delivery_strategy: none

The delivery_strategy option tells to the framework how to deliver the messages. By default, Symfony comes with 4 different strategies:

  • realtime: The messages are delivered in real time.
  • single_address: The messages are delivered to just one single email address.
  • spool: The messages are stored in a queue.
  • none: The messages are just ignored.

It does not matter what the strategy is, the messages are always logged them in the log and they are available in the “mailer” tab in the web debug toolbar.

Mail Transport

The emails are always send them through a transport. You can configure the transport that you want just editing the factories.yml file. The default configuration is:

1
2
3
4
5
6
7
8
transport:
  class: Swift_SmtpTransport
  param:
    host:       localhost
    port:       25
    encryption: ~
    username:   ~
    password:   ~

We can chose between 3 different classes:

  • Swift_SmtpTransport: Uses the SMTP server to send messages.
  • Swift_SendmailTransport: Uses sendmail to send messages.
  • Swift_MailTransport: Uses the PHP native function mail() to send the messages.

In the “Transport Types” section into the official Swift Mailer documentation we can find everything we need about the transport classes and their different parameters.

Source: Symfony’s site

Doctrine vs Propel

UPDATE: Here is a great comparison for these ORM’s for the 2.x versions. Thanks to @Pati for sharing the link.

A quick comparison for the most 2 well known and best ORM‘s for PHP.

Here we will try to make a quick comparison about the most known ORM for PHP. To help developers to take the right decision when we need to decide what is the best ORM which could best adapt to our projects.

These 2 more used ORM are as the post title mentioned Doctrine and Propel.

Features

Both ORMs have many similar basic features, they support all the usual operations for CRUD (Create, Retrieve, Update and Delete), from create a new record to update existing ones. Also, both can generate the PHP classes for you, Propel based on XML while Doctrine based on YAML, And another cool feature they have is that both support different database engines (like Mysql, Oracle, MSSQL, etc).

Both support data validation and model relationships. Additionally, they support simple inheritance, although in Doctrine is called concrete inheritance. Doctrine supports 2 types of inheritance: Simple, where all the classes have the same columns, and the Aggregation inheritance, where we store an additional value in the table which allows us the automatic instantiate of the right model type when we make a query.

Well, we saw they almost share the same features so far, but the following are features only Doctrine has.

Behaviors: Doctrine supports many “behaviors” for its models, for instance, a Timestampable model will automatically create two columns: created_at and updated_at, where we can store the creation and update dates.

Searching: Doctrine has a fulltext search engine.

Plus, Doctrine supports data fixtures and migrations, caching, events, pagination, commands line interface and so on, and we can say in advanced features Doctrine has an advantage compared with Propel.

Usability

Documentation

One of the most important thing is documentation of course. Without a good documentation is hard to use any library. Until the last year (2009) the Propel documentation was one of the major problem for them, and it’s true they are improving it there still are work to do. In the other hand, the Doctrine documentation is great and the community is continuously improving it. So, about documentation concern, Doctrine is clearly the winner.

Libraries Use

The first task we have to do with both ORMs is to build the model classes. Doctrine allows us to just write a simple YAML file, or just PHP code if you prefer it. The Propel proposal is to write a XML to define our model classes, and in my personal opinion I prefer to deal with YAML instead of XML, so point for Doctrine :-).

Database operations

The basic operations with CRUD are very similar in both ORMs, however, there is a big different when we need to do more advanced queries.

Propel uses a Criteria/Peer proposal:

1
2
3
4
5
6
<?php
$c = new Criteria();
$c->add(UserPeer::ID, 10);

//SELECT all "User" models which have 10 as their ID and join all foreign tables.
$users = UserPeer::doSelectJoinFoobar($c);

Doctrine proposal is to use Doctrine_Query and a simple customized SQL named DQL (Doctrine Query Languaje):

1
2
3
4
5
6
<?php
$items = Doctrine_Query::create()
    ->from('User u')
    ->leftJoin('u.Foobar')
    ->where('u.id = ?', 10)
    ->execute();

To set values in our model classes these ORMs utilizes different methods: Doctrine uses magic methods, while Propel generates setters and getters. This feature gives to Propel the advantage of autocompletion in most IDEs.

As conclusion I can say that both ORM are great, but I prefer Doctrine. And, of course, you can put the ‘My opinion’ label to this post.

And in this link you can find a comparison that Symfony made between these 2 ORMs.

What is new in Symfony 1.3 / 1.4

At the end of this month it goes out the last release of Symfony and here we will review what are the new news. If you have already used 1.2 version you will notice a couple of improvements have been added.

Between the new functionalities, the most highlighted are:

Mailer

Symfony 1.3/1.4 comes with a new integrated mailer based on SwiftMailer 4.1. And, to send an email is as easy as we show below using the composeAndSend() method:

1
2
3
4
5
6
<?php
public function executeSendEmail()
{
    $this->getMailer()->composeAndSend('from@example.com', 'to@example.com', 'Subject', 'Body');
}
?>

If you need more flexibility and you need to attach a file, you can use the compose() method and then send it:

1
2
3
4
5
6
7
8
9
10
<?php
public function executeSendEmail()
{
    $message = $this->getMailer()
        ->compose('from@example.com', 'to@example.com', 'Subject', 'Body')
        ->attach(Swift_Attachment::fromPath('/path/to/a/file.zip'));
   
    $this->getMailer()->send($message);
}
?>

Swift Mailer is a great and powerful library, and if you want to know more about it you can check its documentation.

Security

In these versions when you use the generate:app command, the security is already actived by default. The escaping_strategy value is already activated by default, but you can deactivate it with the –escaping-strategy option. Also, for the csrf_secret option, the framework already comes with a random generated keyword and you can change it in the setting.yml configuration file.

Widgets

Labels by default: When a label is auto-generated from the field name, the label is defined without the _id suffix (if it has it). For instance, for the client_id field name, the generated label will be ‘client’ now (it was client_id before).

sfWidgetFormInputText: Now the sfWidgetFormInput class is abstract, and the text input fields should be created with sfWidgetFormInputText.

Forms

sfForm::useFileds(): This new method remove all the form fields, except those passed as argument. This ease the fields visualization in the form view without the need of make an unset() of the unwanted fields. For instance, when we add a new field in the base form, this one do not appear automatically in the form view at least we add it explicitly as an argument of this method:

1
2
3
4
5
6
7
8
9
<?php
class ArticleForm extends BaseArticleForm
{
    public function configure()
    {
        $this->useFields(array('title', 'content'));
    }
}
?>

By default, the array is used to change the fields order; we can pass a second argument as a false value to deactivate this automatic sort.

sfForm::getEmbeddedForm($name): Now we can access a particular embedded form using the getEmbeddedForm() method.

Autoloaders

All the Symfony’s autoloaders are case-insensitive now, since PHP is case-insensitive as well.

Default ORM

Symfony 1.3/1.4 comes with Doctrine as its default ORM.
If we want to use Propel as ORM, we should use the –orm=Propel option:

1
:$ php symfony generate:project foo --orm=Propel

And if we want to do not use Doctrine neither Propel, we can use the –orm=none option:

1
:$ php symfony generate:project foo --orm=none

These are the most highlighted features to me :D. There are a lot more improvements related to widgets, validators, routing, and much more CLI task as well.