Posts Tagged ‘PHP’

Zend Javascript and CSS caching

October 25th, 2012

How often, when developing/testing a website, did you ask your customer to clear his browser cache?
Ok, your client can clear his cache… But what about a live application? How to tell users to clear their cache?

So, if you’re using headLink and headScript view helpers I think this will help. The main idea is to overload Zend’s headLink and headScript and add a “versioning” parameter at the end of the url.
Everytime you make a change in css/js you just have to update the “version” in application.ini.

Attached you’ll find the two classes that overload Zend’s headLink and headScript view helpers. Add those in “library/Ze”.

In Bootstrap.php, you’ll have to let the “view” know of those scripts, so add this line in “_initView()” method (after you initialize view):

1
$view->addHelperPath('Ze', 'Ze');

Same thing, in Bootstrap.php, you’ll have to add your config to registry (in case that isn’t added by now):

1
Zend_Registry::set('config', $this->getOptions());

In the end, don’t forget “versions” in application.ini file:

1
2
assets.css.version = 1
assets.js.version = 1

Aaaaannd…. voila!

Attached Files:

Share

Zend Framework 2 Overview

December 15th, 2011

Check out the upcoming features in Zend Framework 2 and seriously think about making the change after the release:

Share

Zend Model Improvements

March 22nd, 2010

The class I will describe today is an extension of the Zend_Db_Table class that exposes a list of magic functions with the most commonly used operations over the database.

It uses the __call function to add a functions to retrieve records from the database by simply calling a function like: $this->getAllByProductIdAndStatus(1, 'Active'). When calling this function the following two field names are subtracted from the function name: “product_id” and “status”. Each of these fields are set to the parameters passed to the function. After that a query is built using these fields to restrict the result to only those records that have product_id set to 1 and status set to Active. The model defines the following function patterns:

  • const PATTERN_GET_BY='/getBy(.*)/'; – returns only one record or null is none match the fields
  • const PATTERN_GET_ALL_BY='/getAllBy(.*)/'; – returns all the matching records
  • const PATTERN_GET_ALL_LIKE='/getsAllLike(.*)/'; – returns all the records that match the assigned SQL regular expressions
  • const PATTERN_GET_ALL='/getAllRows/'; – returns all records from the current table
  • const PATTERN_FETCH_BY='/fetchBy(.*)/'; – returns only one record
  • const PATTERN_FETCH_ALL_BY='/fetchAllBy(.*)/'; – returns all the matching records
  • const PATTERN_FETCH_ALL_LIKE='/fetchAllLike(.*)/'; – returns all the records that match the assigned SQL regular expressions
  • const PATTERN_FETCH_ALL='/fetchAllRows/'; – return all records from the current table
  • const PATTERN_REMOVE_BY='/removeBy(.*)/'; – removes all the matching records from the current table
  • const PATTERN_COUNT_BY='/countBy(.*)/'; – counts the number of records by fields
  • const PATTERN_COUNT_LIKE='/countAllLike(.*)/'; – counts the number of records using LIKE as a condition operator
  • const PATTERN_COUNT_ALL='/countAll/'; – counts the number of records from the current table

As you can see there are 4 sets of functions:

  1. Functions that start with “get”. These functions return objects (default Zend_Db_Table_Row for single records and Zend_Db_Table_Rowset for multiple records).
  2. Functions that start with “fetch”. These function return arrays. Also they will join with all the tables set in the referenceMap property based on the name of the reference, like so <reference>__<referred_table_field_name>.  An example would be the following: owner__first_name.
  3. Functions that start with “remove”. These functions delete the matching records from the current table.
  4. Functions that start with “count”. These functions return the number of matching records based on the given fields and their values.

Another useful function defined in the model is the “save” function. This function takes only one parameter of type array or object and it inserts the values in the database and returns the generated primary key. By default the “id” field is used as a primary key, but that can be changed by setting the $primary property of the model. If the given array/object already contains the primary key field then the values are not inserted into the database, but rather the record with the matching primary key is updated. The “save” function always returns the value of the primary key field for the inserted or updated record.

In order to access the functions faster and now create objects each time I want to connect to the database I also created a static function named this() that returns an instance of the current Ze_Model class. This way you can get the records from the database by simply calling something like: Model_Users::this()->getByUsernameAndPassword('john','doe');.

You can use this class by adding it into your library/Ze/ folder and use it as the base for your new models instead of Zend_Db_Table class.

I have attached the full source code of the class to this post. I am looking forward to your thoughts and improvements.

Attached Files:

Share

Zend Framework Base Website Structure

March 17th, 2010

I came into contact with Zend Framework a few years ago while writing my own version of a PHP framework.

I worked on a lot of websites written in PHP before that and I always followed the same automated process. After about a year I had a pretty stable version of a small framework. The problem was that it was still lacking functionality that could make developing my websites easier. I was wasting a lot of time writing the same old code again and again.

During my research I realized that there was a lot of existing PHP Frameworks what could do exactly what my code was doing (and a lot more), but in a much easier and better way. So, I started searching for the best framework that I could find. In a short while I found Zend Framework, a powerful Object Oriented PHP Framework that I could extend to my own needs.

Since then I’ve been creating web sites and web applications using exclusively Zend Framework.

Choosing the right architecture for your web application can be at times one of the most important tasks you may have to face when developing a new project.

Luckily the developers at Zend Framework provide us with a great base structure for our new projects. See Zend Framework Documentation: Create your project page for more details on the proposed structure.

In this article we will extend this structure in order to allow us to have a solid structure for all our future web based projects.

Added functionality:

  • Module and layout handling
  • Database metadata caching
  • Base Controllers
  • Set up project folders

Basic Structure

When you create a new project using the Zend Tool script you receive in your bin/ folder from your Zend Framework distribution you will get a structure that looks very similar to:

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
  quickstart
  |-- application
  |   |-- Bootstrap.php
  |   |-- configs
  |   |   `-- application.ini
  |   |-- controllers
  |   |   |-- ErrorController.php
  |   |   `-- IndexController.php
  |   |-- models
  |   `-- views
  |       |-- helpers
  |       `-- scripts
  |           |-- error
  |           |   `-- error.phtml
  |           `-- index
  |               `-- index.phtml
  |-- library
  |-- public
  |   |-- .htaccess
  |   `-- index.php
  `-- tests
      |-- application
      |   `-- bootstrap.php
      |-- library
      |   `-- bootstrap.php
      `-- phpunit.xml

Setting the tests folder aside we are left with three very important folders:

  • application – which will contain all the server side scripting files
  • public – as the name indicates this will contain all the files that should be accessible to our end users without any restrictions
  • library – this will contain our Zend Framework distribution and other classes that you may need to add along the way

Module and Layout Handling

In order for our application to allow us to work with modules it needs to know in which folder we will keep them. Therefore we need to add the following line in the configuration file:

1
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"

After doing this create a new folder called “modules” in the application/ folder. That is all you need to do. You can now add new modules to your website. For an example of what folders should be contained in a module take a look at: Zend Framework Documentation: Module Structure. The only required folder from the presented structure is the controllers/ folder, but you will most likely need the views folder as well.

Layouts are easily set up by creating a new “layouts” folder in your application/ folder and adding the following line to your configuration file:

1
resources.layout.layoutPath = APPLICATION_PATH "/layouts/"

Database Metadata Caching

Before every request to the database you perform using a model, Zend Framework runs a DESCRIBE TABLE query. Therefore it is a great idea to cache this result and not run the same query for each request. You can do this by simply setting the Metadata Cache for Zend_Db_Table like so:

1
Zend_Db_Table::setDefaultMetadataCache($cache);

Base Controllers

There are some operations that you use on a regular basis when working with controllers. For example if you have an AJAX based application you may have some actions that do not require a layout or over a view. For these actions you will have to disable the view and layout all together. It may prove useful to have a base controller where you can all all the methods you require and just extend this controller instead of Zend_Controller_Action.

An example of such a controller is the following class:

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
class Ze_Controller extends Zend_Controller_Action {
    /**
     * Initialize base controller
     */

    public function init(){
        /* Initialize all action controllers here */
    }
    /**
     * Disable layout and view
     * @param bool $disableView [optional]
     * @param bool $disableLayout [optional]
     */

    protected function _disableRender($disableView=true, $disableLayout=true){
        if ($disableLayout)
            $this->_helper->layout->disableLayout();
        if ($disableView)
            $this->_helper->viewRenderer->setNoRender();
    }
    /**
     * Change layout
     * @param string $layout
     */

    protected function _setLayout($layout){
        $this->_helper->layout->setLayout($layout);
    }
}

This controller defines two methods: one for disabling the layout and view, and one for changing the layout. To use it just change the extend class of your controllers from Zend_Controller_Action to Ze_Controller.

Set up project folders

There are a couple of folders that that you need to set up before fully enjoying the benefits of using a Zend Framework project structure. The folders you need to set up are: models/ and forms/.

Add the following method to your bootstrap file:

1
2
3
4
5
6
7
8
9
protected function _initResources()
    {
        $resourceLoader = new Zend_Loader_Autoloader_Resource(array(
            'basePath'  => APPLICATION_PATH,
            'namespace' => '',
        ));
        $resourceLoader ->addResourceType('form', 'forms/', 'Form')
                        ->addResourceType('model', 'models/', 'Model');
    }

The above code adds two new resources:

  • form – Sets up the application/forms/ folder as the location for all your new forms and sets their suffix to “Form_”
  • model – Configures the default model folder as application/models/ and sets the suffix for all your models to “Model_”

Conclusions

The above changes to your base website structure will help you create set up a powerful website structure on which you can create any type of PHP driven web application.

Attached you will find a complete structure for all your new projects. Just download it, unzip it and use it. Make sure you have the Zend Framework library into your include_path or add it into the library folder.

Attached Files:

Share