Federico Cargnelutti

Simple is better than complex. Complex is better than complicated. | @fedecarg

Archive for the ‘PHP’ Category

Increase speed and reduce bandwidth usage with ZF and Apache

with 17 comments

Apache’s mod_deflate module provides the DEFLATE output filter that allows output from your server to be compressed before being sent to the client over the network.

There are two ways of enabling gzip compression:

  1. Using Apache’s mod_deflate
  2. Using PHP’s built-in functions

Encoding the output and setting the appropriate headers manually makes the code more portable. Keep in mind that there are hundreds of Linux distributions, each slightly different to significantly different. To allow portability the application should not make assumptions about the OS or config involved.

Using Apache

1. Enable mod_deflate

Debian/Ubuntu:

$ a2enmod deflate
$ /etc/init.d/apache2 force-reload

2. Configure mode_deflate

$ nano /etc/apache2/mods-enabled/deflate.conf

#
# mod_deflate configuration
#
<IfModule mod_deflate.c>
 AddOutputFilterByType DEFLATE text/plain
 AddOutputFilterByType DEFLATE text/html
 AddOutputFilterByType DEFLATE text/xml
 AddOutputFilterByType DEFLATE text/css
 AddOutputFilterByType DEFLATE application/xml
 AddOutputFilterByType DEFLATE application/xhtml+xml
 AddOutputFilterByType DEFLATE application/rss+xml
 AddOutputFilterByType DEFLATE application/javascript
 AddOutputFilterByType DEFLATE application/x-javascript

 DeflateCompressionLevel 9

 BrowserMatch ^Mozilla/4 gzip-only-text/html
 BrowserMatch ^Mozilla/4\.0[678] no-gzip
 BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

 DeflateFilterNote Input instream
 DeflateFilterNote Output outstream
 DeflateFilterNote Ratio ratio
</IfModule>

Using PHP

Create a gzip compressed string in your bootstrap file:

try {
    $frontController = Zend_Controller_Front::getInstance();
    if (@strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
        ob_start();
        $frontController->dispatch();
        $output = gzencode(ob_get_contents(), 9);
        ob_end_clean();
        header('Content-Encoding: gzip');
        echo $output;
    } else {
        $frontController->dispatch();
    }
} catch (Exeption $e) {
    if (Zend_Registry::isRegistered('Zend_Log')) {
        Zend_Registry::get('Zend_Log')->err($e->getMessage());
    }
    $message = $e->getMessage() . "\n\n" . $e->getTraceAsString();
    /* trigger event */
}

Reference

Use mod_deflate to compress Web content delivered by Apache

Written by Federico

July 6, 2009 at 11:09 am

Format a time interval with the requested granularity

with 8 comments

This class, a refactored version of Drupal’s format_interval function, makes it relatively easy to format an interval value. The format will automatically format as compactly as possible. For example: if the difference between the two dates is only a few hours and both dates occur on the same day, the year, month, and day parts of the date will be omitted.

class DateIntervalFormat
{
    /**
     * Format an interval value with the requested granularity.
     *
     * @param integer $timestamp The length of the interval in seconds.
     * @param integer $granularity How many different units to display in the string.
     * @return string A string representation of the interval.
     */
    public function getInterval($timestamp, $granularity = 2)
    {
        $seconds = time() - $timestamp;
        $units = array(
            '1 year|:count years' => 31536000,
            '1 week|:count weeks' => 604800,
            '1 day|:count days' => 86400,
            '1 hour|:count hours' => 3600,
            '1 min|:count min' => 60,
            '1 sec|:count sec' => 1);
        $output = '';
        foreach ($units as $key => $value) {
            $key = explode('|', $key);
            if ($seconds >= $value) {
                $count = floor($seconds / $value);
                $output .= ($output ? ' ' : '');
                $output .= ($count == 1) ? $key[0] : str_replace(':count', $count, $key[1]);
                $seconds %= $value;
                $granularity--;
            }
            if ($granularity == 0) {
                break;
            }
        }

        return $output ? $output : '0 sec';
    }
}

Usage:

$dateFormat = new DateIntervalFormat();
$timestamp = strtotime('2009-06-21 20:46:11');
print sprintf('Submitted %s ago',  $dateFormat->getInterval($timestamp));

Outputs:

Submitted 3 days 4 hours ago

Written by Federico

June 25, 2009 at 12:49 am

Face Detection Using PHP

without comments

Maurice Svay explains how to detect faces in photos with PHP:

Nowadays, face detection is built in many consumer products (camera obviously, but also Google and iPhoto), and seems to be a pretty common job. So I expected to find many solutions for doing it with PHP. Surprisingly, the only one I could find is OpenCV, an opensource lib that was originally developed by Intel. OpenCV seems to perform well but you need to be able to install it on your server. In my case, I wanted to have a pure PHP solution, so it can work with most hosts.

Face detection in pure PHP (without OpenCV)

Written by Federico

June 24, 2009 at 4:09 pm

Posted in PHP

TypeFriendly: A Documentation And User Manual Builder

without comments

TypeFriendly is a documentation generation script written in PHP5. It was designed to be easy in use and it allows to achieve the first results immediately, a couple of minutes after you start the work. The script contains everything you need to write clear, multilingual documentation for your project, so that you do not have to code everything on your own.

The most important features of TypeFriendly:

  1. Modular documentation structure – it is generated from text files and the structure and navigation are generated from the file names.
  2. Simple syntax – the text is written in intuitive and clean Markdown syntax.
  3. Multilingual support and tools – TypeFriendly allows you to create your manuals in many language versions. It also contains a tool that shows whether the derived languages are up-to-date.
  4. Configurable output formats – currently, TypeFriendly is able to generate the documentation in XHTML (many pages) and XHTML (single page). There is also a third format – metadata – still under development. It will allow to import the docs to a database in order to make an on-line version with, for example, user comments.
  5. Various add-ons such as syntax highlighting, references, class description fields.
  6. Navigation generators.
  7. It is portable – works under Linux, FreeBSD and Windows. All you need is the PHP interpreter available.

TypeFriendly is distributed under the terms of GNU General Public License 3, which means that you can use, modify and share it for free.

Demo
http://static.invenzzia.org/docs/tf/0_1/book/en/index.html

Screenshots
http://www.invenzzia.org/en/projects/typefriendly/screenshots

Source Code
http://svn.invenzzia.org/browser/TypeFriendly/trunk/

Website
http://www.invenzzia.org/en/projects/typefriendly

Written by Federico

May 16, 2009 at 11:30 am

Posted in Open-source, PHP, Tools, Web Apps

Real Time Web-Based Service Monitoring Tool

without comments

phpWatch is a general purpose service monitor that is able to send notifications of outages via e-mail or text-message (SMS). The purpose of this system is to allow administrators to easily check the status of many different services running on any number of servers and also allow developers to interface with the query and notification APIs.

Installation

The basic installation is very simple: chmod config.php to 777 and simply navigate to the install directory in your browser. Fill in the database information and the setup will create the required tables and setup the configuration file as needed. The only required task beyond the automated install is to add cron.php as a cron job (Unix/Linux) or scheduled task (Windows).

SMS Alerts

phpWatch uses pre-existing SMS gateways provided by the cell-carriers themselves. For example, to send a message to a Verizon subscriber with the phone number 123-456-7890, an e-mail can be sent to 1234567890@vtext.com and it will then be forwarded to the individual’s phone.

Links

Written by Federico

May 12, 2009 at 7:34 pm

Posted in Open-source, PHP, Tools, Web Apps

New Zend Framework Book Published

with one comment

This book shows you how to build websites fast using PHP and MySQL. What’s more, it shows you how to supercharge your use of these technologies by taking advantage of a powerful, free web development solution known as the Zend Framework, which helps developers build websites with speed and efficiency.

This book embraces a teaching strategy of learning by doing, showing you how to build website features you’ll actually want to use within your own websites. Among other things you’ll learn how to manage data submitted through web forms, send unformatted and HTML e-mails through your website, manage user registrations, logins, and recover forgotten passwords, and even create the structure for a simple social network.

Along the way, you’ll learn how to take advantage of popular online services such as Google Maps, Amazon Web Services, the Facebook Platform, and PayPal to create even more compelling websites.

Easy PHP Websites with the Zend Framework

Written by Federico

May 11, 2009 at 7:26 pm

Posted in Frameworks, PHP, Programming

Yahoo Open Hack 2009 London

with one comment

Come and join Yahoo! on the 9th and 10th of May in London for 24 hours of learning, hacking, networking and fun.

It’s a two-day event on Saturday 9th of May with a morning of Tech Talks covering a wide range of topics led by some of the Web’s most respected developers. Yahoo will showcase the newest platforms and developer tools for you to play around with, and there will be plenty of experts on hand to answer questions.

Sign Up Now

Written by Federico

May 6, 2009 at 10:34 pm

PHP Support in Google App Engine

with 6 comments

Google App Engine now supports Java, this means that you can write PHP applications using Quercus: Demo script

The App Engine SDK for Java includes:

  • A Web application and Web server (Jetty) that emulates all App Engine services on your local development machine.
  • All the APIs and libraries available on App Engine.
  • Support to upload your application to App Engine.

Learn how to run PHP with Quercus in Jetty Web Server.

Written by Federico

April 13, 2009 at 10:43 pm

Posted in Java, PHP, Programming

An Alternative to Zend_Controller: The Model

with one comment

Part 1 – An Alternative to Zend_Controller: Introduction
Part 2 – An Alternative to Zend_Controller: The Router

Domain Layer

The domain layer is separated from the other layers and has no dependencies on Zf_Controller.

app/
domain/
    Model/
        User.php
        UserDao.php
lib/
    Zend/
    Zf/

Adding the domain directory to your include path allows you to load and access Model classes from anywhere within your project:

Bootstrap file

set_include_path(APPLICATION_PATH . '/../lib'
    . PATH_SEPARATOR . APPLICATION_PATH . '/../domain);

Index Controller

class IndexController extends Zf_Controller_Action
{
    public function indexAction()
    {
        // DAO pattern
        $dao = new Model_UserDao();
        ...
    }
}

The getInstance() method can be used to set or retrieve a singleton instance of a Model class:

class IndexController extends Zf_Controller_Action
{
    public function indexAction()
    {
        $dao = $this->getInstance('Model_UserDao');

        // or...
        $dao = new Model_UserDao();
        $this->setInstance($dao);

        $this->userAction();
    }

    public function userAction()
    {
        $dao = $this->getInstance('Model_UserDao');
        ...
    }
}

Below is an example of the UserDao class that contains methods to insert, update, and retrieve data:

class Model_UserDao extends Zf_Persistence_Db_Adapter
{
    public function find($id)
    {
        $db = $this->getAdapter();
        ...
    }
}

abstract class Zf_Persistence_Db_Adapter
{
    protected $_db = null;

    public function setAdapter(Zend_Db_Adapter_Abstract $db)
    {
        $this->_db = $db;
    }

    public function getAdapter()
    {
        if (null === $this->_db) {
            if (!Zend_Registry::isRegistered('Zend_Db')) {
                throw new Zf_Persistence_Exception('...');
            }
            $this->setAdapter(Zend_Registry::get('Zend_Db'));
        }

        return $this->_db;
    }
}

More Info

Written by Federico

April 13, 2009 at 2:46 pm

An Alternative to Zend_Controller: The Router

with 3 comments

Part 1 – An Alternative to Zend_Controller: Introduction

Here’s the good news: Zf_Controller doesn’t have a Router. It uses a very simple mapping to determine the name of the controller and action. Optionally, you may define parameters in the URI, for example:

http://domain.com/controller/action/value1/value2

An example of how routes are matched:

URI: http://domain.com/news/tag/zend-framework

Controller

class NewsController extends Zf_Controller_Action
{
  public function tagAction()
  {
    print_r($this->_getAllParams());
  }
}

Outputs

Array
(
    [controller] => News
    [action] => tag
)

Variable Defaults

It is often helpful to be able to assign default values to parameters that aren’t passed, that way we don’t have to check if the parameter has been set or not. The $_params property is an array with keys representing variable names and default values.

URI: http://domain.com/news/tag/zend-framework

Controller

class NewsController extends Zf_Controller_Action
{
  protected $_params = array(
    'name' => null,
    'show' => 10
  );

  ...
}

Outputs

Array
(
    [controller] => News
    [action] => tag
    [name] => zend-framework
    [show] => 10
)

A parameter sent via the URI will always overwrite a default parameter. That’s the whole point of using default values.

Variable Requirements

The $_paramsMatch property is used to set variable requirements. These are defined as parts of a regular expression:

URI: http://domain.com/news/tag/zend-framework/50

Controller

class NewsController extends Zf_Controller_Action
{
  protected $_params = array(
    'name' => null,
    'show' => 10
  );

  protected $_paramsMatch = array('show' => '\d+');

  ...
}

In the example above, Zf_Controller will assign the value to the “show” variable only if the value is a number. If not, it will assign the default value, in this case “10″.

If you think that you need more flexibility than this, I suggest extending Zend_Controller_Action instead.

Part 3 – An Alternative to Zend_Controller: The Model

Written by Federico

April 8, 2009 at 7:45 pm