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

Execute native SQL with Doctrine

We can execute raw SQL queries with Doctrine ORM.

If you already used this awesome library you already know all the features Doctrine supplies us at the time to interact with our database. The DQL (Doctrine Query Language) language is a very powerful and one of the most main feature of Doctrine, but, sometimes we have to face really advanced queries and with DQL it could be a little tricky to do it (in version 2 it will be improved).

If you need to do advanced and complicated queries (or not), Doctrine gives you the ability to execute native/raw SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

// we build the query
$query = "select id from tabla";

// gets the connection singleton
$con = Doctrine_Manager::getInstance()->connection();

// executes the query
$st = $con->execute($query);

// retrieves the results
$rs = $st->fetchAll();

// Or if you want the associative results
$rs = $st->fetchAssoc($query);

That’s it.

MVC: Design Pattern

A short description about the Model-View-Controller design pattern.

One of the most known patterns in the web is the MVC (Model-View-Controller) architecture, which is very used in software engineer and it’s composed by 3 layers:

  • The Model is the business logic, which represents the basic information which the application works. To persist that information, apps can use different storage systems such as databases. Although this is not a concern for this layer.
  • The View renders the Model in the browser to allow the user to interact with it. This layer could be extended to support multiple view sub-layers.
  • The Controller responses to the user’s actions and executes the necessary changes in the Model.

mvc

The MVC architecture splits the business logic (Model) and the presentation (View), resulting in a very maintainable code. For instance, if an application should run in both desktop web browser and in mobile browser, we just need to work in different presentations (views) while the controller and the model is shared. The model abstract the business logic, which makes the view and controller independent of the business logic and data access.

How to merge on subversion

In this post we will show how to do a merge between a branch and the trunk.

In a previous post we saw how to use subversion from the command line to manage our project repositories, now we will see how to do merge from a branch to a trunk.

We use branches for new features to be developed, while the trunk is normally used as the main development thread. To do a merge we should use the following commands:

1. Check out a copy of the trunk:

1
user@unix:~$ svn co https://svn.hasheado.com/myProject/trunk

2. Now, we do a check out of the branch we want to merge:

1
user@unix:~$ svn co https://svn.hasheado.com/myProject/branches/1.0.1

3. We should change the work copy to the last branch and find in what revision we are:

1
2
user@unix:~$ cd /path/to/branches/1.0.1
user@unix:~$ svn log --stop-on-copy

This last command should show us the changes those did made since the creation branch. Take note of that number (should be in the way of rXXX, where XXX is the revision number).

4. Change our work copy to the trunk and do an update:

1
2
user@unix:~$ cd /path/to/trunk
user@unix:~$ svn update

That update will update our work copy to the most recient revision, and it will tell us what revision is. We should take note of this revision number (“at revision YYY”).

5. Now, we could simulate the merge:

1
user@unix:~$ svn merge --dry-run -r XXX:YYY https://svn.hasheado.com/myProject/branches/1.0.1

The –dry-run option simulates the merge, but it does not make it, in that way we can see what files will be merged and if we should resolve some conflicts.

6. After review the simulation output, we should do the merge:

1
user@unix:~$ svn merge -r XXX:YYY https://svn.hasheado.com/myProject/branches/1.0.1

7. And at the end, do a commit to the repository:

1
user@unix:~$ svn ci -m "MERGE myProject from branch 1.0.1"

That is all, the merge is done.

NOTE: Take in account that the url used are just samples.

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:

Use utf8 in Symfony with Doctrine

Here we will see how to configure Doctrine to use utf8 in Symfony.

So, we will set the charset and the collation of our database to use utf8, which most of the time is very useful, for instance, when we want to use a database with support to internationalization (i18N).

To do that we have three possibilities to see:

First, we can edit the config/ProjectConfiguration.class.php file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class ProjectConfiguration extends sfProjectConfiguration
{
    public function setup()
    {
        $this->enablePlugins('sfDoctrinePlugin');
    }

    public function configureDoctrine(Doctrine_Manager $manager)
    {
        $manager->setCollate('utf8_unicode_ci');
        $manager->setCharset('utf8');
    }
}

The second one is to set the configuration in the config/databases.yml file:

1
2
3
4
5
6
7
8
9
10
11
all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn:      mysql:host=localhost;dbname=myDatabase
      username: myUser
      password: mySecret
      attributes:
        default_table_type:    InnoDB
        default_table_collate: utf8_unicode_ci
        default_table_charset: utf8

And the last one is to set the options in our schema (config/doctrine/schema.yml):

1
2
3
4
options:
  collate: utf8_unicode_ci
  charset: utf8
  type: InnoDB

I hope this is helpful for you.

Symfony: generate-admin filters customization

In this post we will see how to customize the generate-admin filters to get more customized filters adapted to our needs.

If some time we used the Symfony generate-admin we could see that we have the ability to filter what data to show. These filters allow us to filter by whatever existing field in the entity. Now, we will see how to add a customized field to the filters, so we can filter according to our needs.

Let’s suppose we have an User and Phonenumber objects and in the phonenumbers list we want to filter by user. To do that we can modify the generator.yml file in the phonenumber module. In phonenumber/config/generator.yml:

1
2
3
config:
  filter:
    display: [ another, field, user_by_name]

Also, we need to define the widget and validator to this new field in lib/filter/doctrine/PhonenumberFormFilter.class.php:

1
2
3
4
5
6
7
8
9
<?php
public function configure()
{
    //...
    $this->setWidget('user_by_name', new sfWidgetFormFilterInput(array('with_empty' => false));
 
    //...
    $this->setValidator('user_by_name', new sfValidatorPass(array('required' => false));
}

In the same form class we need to overwrite the getFields() method with the new added field:

1
2
3
4
5
6
7
8
<?php
public function getFields()
{
    $fields = parent::getFields();
    $fields['user_by_name'] = 'custom';
   
    return $fields;
}

And last, we need to add the method which does the filtering, this field follows the convention addColumnNameColumnCriteria:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
public function addUserByNameColumnQuery($query, $field, $value)
{
    $text = $value['text'];
    if ($text) {
        $query->leftJoin($query->getRootAlias().'.User u')->andWhere('(u.first_name LIKE ?
            OR u.last_name LIKE ?
            OR u.username LIKE ?)'
, array("%$text%", "%$text%", "%$text%"));
    }
   
    return $query;
}

Done. We have a customized filter.

Symfony: the new definitive guide

The new Symfony book is already available, updated for 1.3 and 1.4 versions.

A few days ago the last definitive guide for Symfony has go out, which covers the last 1.3 and 1.4 versions of this already popular PHP framework. In this opportunity the name of the book is “A gentle Introduction to Symfony”.

In this new edition the two first chapters talk a little more about the framework philosophy. Also, there are some new chapters, one dedicated for Doctrine, another one for Symfony Form framework, and another one for emails. In summary, we can learn about:

  • If we want to learn about Symfony, we should read the Practical Symfony book if you want to learn the framework with a sample project; or we should read A Gentle introduction to symfony book if you want more theory and further explanations about main features.
  • If you want to find about how to configure Symfony we should read the Reference guide book.
  • If we want to learn more about Symfony about advanced stuff we should read More with symfony book.

definitive_guide