Starting with Zend Framework

published on October 07, 2008.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

Zend Framework is a big & heavy object-oriented framework for PHP. I started working with ZF a couple of months ago, I liked it’s documention (it’s very well documented) and decided to stick with this framework. Here is the latest version of the framework — at the time of writing v1.6.1.

It supports the MVC pattern, which helps separating business logic from viewing logic. It supports a great number of API’s, such as Delicious API, Flickr API, Yahoo API, Akismet API and many more.

The advantages of using a framework is that it is enforcing the developer to write code using a coding standard, it is well documented and well supported, and it is a lot easier to work in a 2+ person team using a framework. If you are a one—man team, someday you may want to add more developers to your projects; the process of their settling in will be very comfortable if you are using a framework.

Choose yourself a framework that best suits your needs, or write your own (be sure to make good documentation, also!). To be honest, I wasn’t looking at other frameworks, just ZF, but I knew right away that it is good for me. Prior to this post I did a little research on other frameworks, and I’m still sure that I made the right choice by choosing ZF.

You can read a bit more about ZF in general on the overview page.

How does it work?

Before anything, we should take a look how does the ZF work, when used in the MVC manner. ZF has a thingy, called Front Controller. When a user is accessing a web page, the Front Controller is called: it’s determining what should be done with the input and which further objects should be instantiated and methods called, and in what order.

E.g., if one makes a page request like: http://example.com/news/last/, first, the Front Controller is called. The Front Controller sets up the environment, loads up some files and classes, etc., then it calls a controller called “News” and an action called “Last” which is to be found inside the “News” controller. If it fails to find the “News” controller or the “Last” action, than it can show the user some error page, or to print out the error itself, depending how it is set up. If everything is OK, then it shows the user the content…

This explanation is very basic, as I intend to dedicate one big post to the Front Controller itself, going deep into details…

Some terms explained

Bootstrap file: all page requests are routed through this file, the Front Controller object is created here.

A module is a part of an application which has it’s own controllers, actions, view scripts, models, configuration files. For example, a page can have a default module and a blog module, where each module has its own Index Controller, Administrator Controller, and have its own unique controllers, like a Comments Controller for the blog module.

A controller is a class which has its own actions and can have its own functions. It controls the data received from the user or from the database, and decides what to do with it. The controller is responsible for one set of things, e.g. a News Controller would list latest news, list news from a particular source, show the archive, etc.

An action is a function inside a controller, which is responsible for doing some action, e.g. action for showing news.

A model receives data from the Controller, and sends data to the Controller. Database related stuff — selecting, inserting, updating, deleting — should be only in the model. Filtering data that is to be inserted into the database should be done in the Controller, not in the model.

A view script is responsible to show the data received from the Controller to the user.

A view helper script is to help to do some automating in the view scripts, like formatting dates, generating form elements, etc.

Just for the record, in further examples, “Dummy” will be referring to a module, “Foo” will be referring to a controller inside the “Dummy” module and “Bar” will be referring to an action inside the “Foo” controller.

Basic file structure

Here’s an example of a file structure for a ZF based application — after the # sign are comments:

/
|--library/
|  |--Zend/ # Zend core
|--application/ # Core of our application
|   |--default/ # The Default module
|       |--config/ # Some configuration files
|          |--config.ini
|       |--controllers/ # Controllers go here
|          |--IndexController.php
|          |--FooController.php
|       |--models/ # Models...
|          |--ModelName.php
|       |--views/ # View related stuff...
|          |--helpers/
|          |--scripts/
|             |--index/ # View files for the Index Controller
|               |--index.phtml # For the default index action
|             |--foo/ # View files for the Foo Controller
|               |--index.phtml # For the default index action
|               |--bar.phtml # For a bar action in the Foo Controller
|             |--layout.phtml # For layout
|   |--dummy/ # A Dummy module...
|       |--config/
|          |--config.ini
|       |--controllers/
|          |--IndexController.php
|          |--FooController.php
|       |--models/
|       |--views/
|          |--helpers/
|          |--scripts/
|             |--index/
|               |--index.phtml
|             |--foo/
|               |--index.phtml
|               |--bar.phtml
|--public/
   |--css/
   |--images/
   |--js/
   |--.htaccess
   |--index.php

With this file structure, http://example.com/ should point to the public folder; this way, the application or the library can not be accessed through the browser, which improves security of the application.

The .htaccess file

The .htaccess file’s responsibility is to route requests to existing resources (existing symlinks, non-empty files, or non-empty directories) accordingly, and all other requests to the front controller. Example:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php

The bootstrap file

The biggest problem is setting up correctly the bootstrap file. Here’s an example of my bootstrap file, I use it on several projects, never had any problems :)

<?php
/**
* This is a general bootstrap file, change it to fit your needs
* Pay attention to the paths
*
*/
error_reporting(E_ALL|E_STRICT);
ini_set('display_errors',1); // set this to 0 on live version

// This is my timezone, change it to yours
// See timezones here: http://www.php.net/timezones
date_default_timezone_set("Europe/Belgrade");

/**
* We need to set some include paths
* To the library
* And to the models
* And add it to the current include path
*
*/
set_include_path('.' . PATH_SEPARATOR . '../library' .
					   PATH_SEPARATOR . '../application/default/models' .
                       PATH_SEPARATOR . '../application/dummy/models' .
					   PATH_SEPARATOR . get_include_path());

include("Zend/Loader.php");

/**
* This little fella loads up a class when needed
* So we don't need to bother with including class files
*
*/
Zend_Loader::registerAutoload();

/**
* This config part is needed only when you
* store stuff for db connections in a .ini file
* I do it this way all the time, so it's a part of my general bootstrap
*
*/
$config = new Zend_Config_Ini('../application/default/config/db_config.ini', 'offline');
$registry = Zend_Registry::getInstance();
$registry->set('config',$config);

// Only needed if you plan to use layouts in your app
Zend_Layout::startMVC();

/**
* Get an instance of the Front Controller
* Tell him where to look for controllers
* And off we go!
*
*/
$frontcontroller = Zend_Controller_Front::getInstance();
$frontcontroller->throwExceptions(true);
$frontcontroller->setControllerDirectory(array(
        'default'   =>  '../application/default/controllers',
        'dummy'       =>  '../application/dummy/controllers'
        ));
$frontcontroller->dispatch(); // GO!!!

This kind of bootstrap file should be enough in most cases; it is for me.

This post is starting to get out of control, so I’ll stop here for now. Next time I’ll show some basic stuff with controllers, actions, views etc. Until then be sure to get familiar with the coding standard, especially with the naming conventions.

Hope that this text isn’t too confusing. I tried to keep it simple and explain all that is needed for starting with Zend Framework.

Any thoughts on ZF, or frameworks in general? Do you use any?

Wordpress paging navigation

published on October 06, 2008.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

As I’m not a big fan of Wordpress plug—ins, and I wanted to use a normal page navigation, not just the default “Previous posts” and “Next posts”, I decided to play around a bit and create my own paging navigation, or pagination.

Preparation

First, I wrote on a piece of paper which links I need: first page, last page, next page, previous page and the links with the page numbers. Next, I needed to see what functions are already in Wordpress, to reuse as much as I can. After a little searching, I found that the functions for the default navigation are located in the link-template.php file, under the wp-includes folder. There are the functions for the next and previous pages, and the function that creates the URL. Furthermore, I wanted a sliding pagination (like Yahoo has on it’s search page), ‘cause it’s easy to use and looks cool.

The function

So, let’s take a look at the code. I called the function simply get_pagination; it’s quite self—describing. I put it in the link-template.php file, that way, all functions for navigation are in one place.

<?php
/**
* A pagination function
* @param integer $range: The range of the slider, works best with even numbers
* Used WP functions:
* get_pagenum_link($i) - creates the link, e.g. http://site.com/page/4
* previous_posts_link(' &laquo; '); - returns the Previous page link
* next_posts_link(' &raquo; '); - returns the Next page link
*/
function get_pagination($range = 4){
  // $paged - number of the current page
  global $paged, $wp_query;
  // How much pages do we have?
  if ( !$max_page ) {
    $max_page = $wp_query->max_num_pages;
  }
  // We need the pagination only if there are more than 1 page
  if($max_page > 1){
    if(!$paged){
      $paged = 1;
    }
    // On the first page, don't put the First page link
    if($paged != 1){
      echo "<a href=" . get_pagenum_link(1) . "> First </a>";
    }
    // To the previous page
    previous_posts_link(' &laquo; ');
    // We need the sliding effect only if there are more pages than is the sliding range
    if($max_page > $range){
      // When closer to the beginning
      if($paged < $range){
        for($i = 1; $i <= ($range + 1); $i++){
          echo "<a href='" . get_pagenum_link($i) ."'";
          if($i==$paged) echo "class='current'";
          echo ">$i</a>";
        }
      }
      // When closer to the end
      elseif($paged >= ($max_page - ceil(($range/2)))){
        for($i = $max_page - $range; $i <= $max_page; $i++){
          echo "<a href='" . get_pagenum_link($i) ."'";
          if($i==$paged) echo "class='current'";
          echo ">$i</a>";
        }
      }
      // Somewhere in the middle
      elseif($paged >= $range && $paged < ($max_page - ceil(($range/2)))){
        for($i = ($paged - ceil($range/2)); $i <= ($paged + ceil(($range/2))); $i++){
          echo "<a href='" . get_pagenum_link($i) ."'";
          if($i==$paged) echo "class='current'";
          echo ">$i</a>";
        }
      }
    }
    // Less pages than the range, no sliding effect needed
    else{
      for($i = 1; $i <= $max_page; $i++){
        echo "<a href='" . get_pagenum_link($i) ."'";
        if($i==$paged) echo "class='current'";
        echo ">$i</a>";
      }
    }
    // Next page
    next_posts_link(' &raquo; ');
    // On the last page, don't put the Last page link
    if($paged != $max_page){
      echo " <a href=" . get_pagenum_link($max_page) . "> Last </a>";
    }
  }
}

The “range” is the range of the sliding effect, i.e. how many numbers are shown besides the current number: if the range is 4, and the current page is 5, then the numbers 3, 4, 5, 6 and 7 are visible.

Usage

It’s quite simple to use it: where the pagination is needed, just call the get_pagination() function, and it will show up. Add some CSS style to it, and your good to go.

Hope someone will find this useful :)

Smush your images!

published on September 30, 2008.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

I just found a nice web site where you can “smush” your images — Smushit.com. SmushIt takes an image and removes all unnecessary information about it: when was it last edited, what image editor was used etc., but keeps the quality of the image! This is more than useful for sites where there are lots of images.

There are several ways to provide images to SmushIt:

  • Upload an image
  • Provide an URL to the image
  • Use the Firefox SmushIt add-on

The first two ways are quite obvious; provide an image and it’ll process it in a few seconds.

The Firefox add-on is pretty cool: open up a web page where are the images you want to smush, click the SmushIt add-on icon (it’ll be in the right corner of the status bar), it will take you to their site and process all the images found on your web page.

When the processing is complete, there will be a table showing details about the smushing. Also a download link will be provided, to download the smushed images in one zip file.

Now run little lurker and smush your images :)

Regular expressions with PHP

published on September 22, 2008.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

I just want to write some real examples. These regexps are (and always will be, ‘cause I plan to write several posts on this topic) for the PHP’s PCRE library. Here’s a good PHP PCRE cheat sheet, it’s an excellent resource for regexps. If you know nothing about regexps, first read this Wiki page.

Regexps for anchor tags

A common case is when you have a source of some web page and you want to parse out all the links from it.
An anchor tag goes something like this:

<a href="http://example.com/" title="Some website">Website</a>

Also it can have more attributes, like class, target etc. Knowing how it’s built up, we can start writing a pattern, depending on what we want.
Here are some examples, some explanations are in the comments:

<?php
// Regexp examples for <a> tags

/**
* Different combinations...
* $matches_comb[0] contains the whole <a> tag
* $matches_comb[1] contains what's inside the "href" attribute
* $matches_comb[2] contains what's after <a> and before </a>
* with the "s" modifier mathces <a> tags that are broken in several lines,
* ie. matches <a> tags with newlines
* without the "s" modifier, matches only <a> tags without a newline
*/
preg_match_all(
    '#<a\s.*href=["\'](.*)["\'].*>(.*)</a>#isxU',
    $string,
    $matches_comb
);

/**
* Match only what's inside the href attributes...
*/
preg_match_all(
    '#<a\s.*href=["\'](.*)["\'].*>.*</a>#isxU',
    $string,
    $matches_href
);

/**
* Match only what's inside the href attirbutes,
* only when it starts with http:// and includes http://
* $mathces_href_http[0] contains some trash also, nevermind,
* $mathces_href_http[1] contains exactly what we need
*/
preg_match_all(
    '#<a\s.*href=["\'](http://.*)["\'].*>.*</a>#isxU',
    $string,
    $matches_href_http
);

/**
* Match all Email addresses - mailto:
*/
preg_match_all(
    '#"mailto:(.*)"#',
    $string,
    $matches_emails
);

?>

Play around with these patterns, see what’s for what, experiment, that’s the best way to learn regexps.

Do you have some more regexps for links? Some better ones than these here?

Happy hacking!

Tags: example, pcre, php, regex, regexp.
Categories: Development, Programming.

about:license

published on September 13, 2008.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

I don’t know about you, but I’m not really good with all the legal mumbojumbo. All these licenses and agreements, they sound to me like they are not written to be read by human beings. Not to mention a bunch of terms that sound similar, but are not at all. As a person who makes and uses all kind of software, I feel like I should know more about licenses; what can and what can not be done under a specific license.

There are 2 major group of licenses: for proprietary and for open source software. Currently, I’m not interested in proprietary licenses, so, I won’t write about them; you can read more on Wikipedia: Proprietary software.

On the other hand, I’m very interested in Open Source Licenses…

Some terms explained...

It is easy to mix terms like free software, open source software, freeware and such, so I’ll try to explain them as I understood them. My main reference for this is Wikipedia.

  • Free software (FS) “free” as in “free” speech, not as in free beer. FS must be free to run, copy, distribute, study, change and improve by users. With every distribution of a FS, it’s source code must be provided also. FS can be charged. Read more detailed about the philosophy of FS.
  • Open source software (OSS) — the difference between FS and OSS is very little: if I got it right, besides the philosophy, the difference is that OSS can not be charged. Read more about OSS definition and about the differences here and here.
  • Freeware software (FWS) — in most cases FWS is a proprietary software made available free of charge, but the source code is not published.
  • Shareware software (SWS) — this kind of software in most cases is available on a trial period, or it’s use is limited in some other way. To use the full software, without trial periods and limitations, users must buy the license for that SWS.
More about software categories can be found on the GNU Project page.

The reason we are here...

On the website of Open Source Initiative there is a list of (probably) all open source licenses out there. I won’t get into all of them, just the most popular ones and ones that interest me.

GNU General Public License

Probably the most used one is the GNU General Public License, with it’s latest version 3.0. The author of this license is Richard Stallman, the founder of the Free Software Foundation.

This license guarantees freedom for software authors and users; freedom to (re)distribute, modify, give and receive source code of the software and use parts of its code in other free software. If wished, free software can be charged, but must guarantee these freedoms to users of this software. Any redistributed or modified version of the original free software must stay under this license. If a free software is changed by another author, it must be marked as changed, so if any problem occurs with the changed version, the problems will not be attributed by mistake to authors of previous versions.

Software under the GNU GPL can be linked only to other software which is also licensed under the GNU GPL. Software that links to a software under the GNU GPL must also be under the GNU GPL.

If someone sees a violation of a GNU GPL, here’s what he should do: Violations of the GNU Licenses.

GNU Lesser General Public License

GNU LGPL is a more permissive version of GNU GPL. It is mainly used for software libraries, but can also be applied to some stand-alone applications. A software under the GNU LGPL can be linked with software that is not under the GNU GPL or GNU LGPL; that software can be another free software or even a proprietary software.

Using GNU LGPL for libraries is discouraged.

The BSD License

The BSD License is a permissive license; conditions are that the original copyright notice, the list of conditions and the disclaimer must be included with every redistribution of the software. The software can be, with or without modifications, redistributed and used. It can be used in other free software or in a proprietary software. Another restriction is that the author of the software can not be used to promote modified versions of the original software, without his or hers written permission.

The MIT License

The MIT License is also a permissive license; it is very similar to the BSD License. Difference is that the author of the original software can be used for promotion without permission, if not stated otherwise in the license.

Other licenses

I found these 4 licenses to be the most interesting ones. Others are very similar, so I will not go into them — maybe in some future post.

I hope someone will find this little reading helpful. Any thoughts on this topic?

Btw, I recommend a good documentary movie, Revolution OS. It tells about the free software movement and the open source. Notable speakers are Linus Torvalds, Richard Stallman, Eric Raymond, Bruce Perens and others. Enjoy :)

Robert Basic

Robert Basic

Software engineer, consultant, open source contributor.

Let's work together!

If you require outsourcing or consulting help on your projects, I'm available!

Robert Basic © 2008 — 2019
Get the feed