With the release of the new Zend Framework 1.7.3 a few nuggets were released. One of those nuggets was the extension support for JQuery UI Widgets. Featuring Dialog, Tabs, and Date Selection widgets among other bug fixes. (A full list of updated Zend 1.7.3 release notes can be seen here)
With the release I started to dig into my current projects and started to update my forms. Adding widgets here and there. In the process I learned thing or two and just wanted to share.
Outline
What are we going to cover?
All required Files and packages.
Installation of these files and packages
Examples – Dialog, DatePicker Widgets as well as their API.
Links to helpful readings
Required Files
If you havent download the latest release, 1.7.3, do so now (click her). Once your done downloading unzip the filea nd open the directory extras/library. This is the directory which contains the ZendX folder.
The latest Zend Framework release comes with an additional library, ZendX. These are extensions which are not part of the Core of the framework. Currently the library contains 2 componenets; the JQuery and the Console components.
Copy the ZendX folder into the folder which contains your current installation of the Zend library. On my webserver the directory structure looks like this after I copy ZenX into the directory . (Yes
You now need the JQuery UI library. To take advantage of the latest and greatest your going to need the release candidate (jquery 1.6rc6), download it and unzip it.
Place the files
themes
ui
external
jquery-1.3.1.js
inside your public directory. Your final directory structure should look something similar to this:
Required Files are now installed. Identifying ZendX_JQuery to your Zend Application
Since the ZendX_JQuery is a View_Helper extension and not part of the main library we need to register it as a plugin using the Zend_View addHelperPath() method.
Open your bootstrap file. public/index.php and copy the below script into it.
$view = new Zend_View();
$view->addHelperPath('ZendX/JQuery/View/Helper', 'ZendX_JQuery_View_Helper');
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
Adding the information to the bootstrap file will allow you to use the ZendX_JQuery throughout your application. From now on the only item you need to include in your View are the styleSheet to implement using the jQuery() addStylesheet()
method and the jQuery() setUriLocalPath() method in your View.
The addStylesheet method will add the stylesheet. If your setup is identical to one shown above you can use the string “/js/themes/base/ui.all.css” to refernce the css file required. (ZF reference manual mentions flora css, i could not find it)
The setURiLocalPath() will add the js library to use. Set it to “/js/ui/jquery.ui.all.js”.
Well get to see how to use these jQuery methods now.
Putting the pieces together – Examples Were going to implement 2 quick examples which will get us started on the right foot by implementing a Date-Picker and a Dialog.
Date Picker
The first example demonstrates the use of the View Helper DatePicker.
The full method accepts 4 parameters with the third parameter accepting an array containing options shown here.
The example shown above adds the stylesheet between the head node and places the js file at the very end of our HTML. Placing the js at the very end of the body is critical to do. Placing it anywhere else will cause mixed results when executing Ajax features.
The example above also demonstrates how to format the date for the specific field using one of the parameters. Go ahead and give it a try, you should see something like the below figure.
Dialog Boxes
A dialog box is the Web 2.0 equivalent of the alert() javascript popup. Using the dialogContainer method we can add a dialog box to our page. Below is an example of a dialog box which uses parameters.
If you tried the example in the ZF Reference manual and didn’t have this work for you. Dont worry, change ‘dialog’ to ‘dialogContainer’ and you should be able to get it working.
jQuery()->setUiLocalPath(”/js/ui/jquery.ui.all.js”);?>
For additional parameters available for the dialogContainer take a look at the JQuery API for the UI widget here. Try out the View, you should see the Dialog window shown below.
Thats it. Set up is done, you know the requirements for the JQuery UI Widgets, and you created 2 widgets. Take a look at some of the links below that helped me get started.
There are a few quarcks i havent figured out yet such as the inability to move the dialog box using FF 3 and currently playnig around with the other widgets so Ill update as I go. Next on the docket. Progress bar and File Uploading using Jquery extension.
Work has been overwhelming lately and frustrating but there was an interesting question asked by one of the developers at work. Can the Zend Framework run without the .htaccess file? The answer, Yes.
Why do we need the .htaccess file
First off why is the .htaccess file required in the first place by Zend Framework? Think of the .htaccess file as a funnel.
In a funnel, you poor water/liquid/stuff into the end contaning the larger diameter. The “stuff” is then squeezed out of a small single point at the opposite end. In the web world the “stuff” is web traffic and the the single point is where all the traffic goes through, in this case its the .htaccess file.
The .htaccess file will send all incoming traffic to your Front Controller which handles routing and dispatching etc.
Removing .htaccess from the process.
For this im going use Apache 2.2. Start off by opening up the httpd.conf file located in the the conf folder of your Apache installation. Somewhere near the bottom add the following lines.
#Application Specific Include file
Include conf/extra/httpd-zf.conf
This will allow Apache to add addition configuration settings once Apache is restarted and its a great place to isolate application specific Apache settings.
Now, go ahead an create the include file, “httpd-zf.conf” inside the APACHE_HOME/conf/extra/ directory and place the ReWrite rules which were originally in your .htaccess file into
it. Hit save, remove the .htaccess file, and restart Apache. You should see your Zend Framework application running.
Why do this?
Speed. Your application must always read the .htaccess file when someone visits the site. Removing this extra layer and placing it into the Web Server itself will reduce the amount of time a page loads.
Last week ZF 1.8 was released and this weekend I spent the better part of it looking through the documentation and over a few of the items released within this package. A few standouts include:
Zend_Tool
Zend_Tag
The Cloud computing components
For more information heres the complete list of features released. I also had a questions for the Zend folks regarding Zend Tool on the page.
Coming up I plan to take a stab at Zend_Tool_Framework_Provider and create a simple example on how use and implement.
A few people we’re having issues installing Zend_Tool on Windows, hell I was having trouble myself since all of the tutorials out there are either Macs or Red Hat based. So dont feel bad if your reading this . I thought i would take some time and create a tutorial, from the ground up and learn a few things myself along the way. So here we go!
Step one Installing PHP (if you havent yet)
If you have PHP already installed skip this section and head over to “An overview of the installation”. Eeryone else, head over to the PHP site, php.net and download the latest and greatest. As of this writing the latest Windows installer is php-5.2.9-2 msi. Download the executable. Yea so what I use executable and you should too its easier to install and configure on Windows.
Once the file downloads, double click the installer, click “next” a few times, and stop when you reach the “Choose Items to Install”.
Choose Items to Install
Once you reach this point your going to check off which extensions you want installed. By default the installer has a few modules turned off but you can easily turn them on by checking off the items to install. Make sure that the “CLI Executable” has no red x marks next to it as shown in the neat picture to the left. If it does click on the “X” and select, “Will be installed on local hard drive”. By doing this your going to installed the php.exe file as well as allow the executable to automatically update and create System Variables. Click “Next”, then “Install” and watch it go.
An overview of the Installation and Required System Variables
When the installation is done you should have a new directory, C:\Program Files\PHP (if you didnt change the default location). This contains the php.exe file along with a number of other things. You should also have some updates to your environment variables. Open the Environment Variables window by right clicking on “My Computer” , “Properties”, “Advanced”, “Environment Variables” . At the bottom of the window you should have 2 System Variables, “Path” and “PHPRC”. Make sure “Path” contains the “C:\Program Files\PHP\;” (Replace with the location of your PHP directory) and make sure PHPRC contains, “C:\Program Files\PHP\” (Location to your php.ini file) . If all the variables are set click “Ok” and head onto the next section.
Verifying Installation.
Now to check that the installation went smoothly. Open a command line window. You do this by going to “Start”, “Run”, and then typing in “cmd”, then click “Ok”. Once the command line window appears type in: php –version
You should see:
If you do great! Your done with PHP. Let’s install Zend Framework now.
Installing Zend_Tool
If all went well, now its time to install Zend_Tool. Download the latest Zend Framework (latest is 1.8.1) and extract the files somewhere onto your system. Move the files
bin/zf.php
bin/zf.bat
into the directory C:\Program Files\PHP and place all the content of the library folder into the C:\zf directory. Many tutorials recommend installing the library in your PHP includes directory but I decided to install it under C:\zf to demonstrate how to use ZEND_TOOL_INCLUDE_PATH environment variable since the library can practically live anywhere when your developing sites. The full path to your Zend Framework instillation is now, C:\zf\library\Zend.
Setting up ZEND_TOOL_INCLUDE_PATH
Open the Environment Variable window again and create a new environment variables under the “System Variables” section. In the “Variable Name” text field enter, “ZEND_TOOL_INCLUDE_PATH” and in the “Variable Value” text field enter “C:\Program Files\PHP\includes\library\” (path to the Zend Library minus the Zend portion). Click ok to close out the “New System Variable” window and then click “ok” once again to close the “Environment Variable” wndow. Time to check if Zend_Tool works.
Verify Installation
If you have any command line windows open, close them and then reopen one. Type in zf show version you should see the below:
Useful commands.
Your set to create your projects , controller, actions now. Below I added a few commands I tend to use.
Create Project
zf create project helloworld
Create a new controller (below commands must be issued within project directory)
zf create controller controller1
zf create controller controller2
Create a few actions
zf create action action1 controller1
zf create action action2 controller2
About 2 months ago I sat in on a PHP performance session at work taught by non other than Rasmus Lerdof. Aside from creating PHP he had some really neat stuff to talk about concerning performance. Most of the presentation came from the php.net site, talks.php.net. Take a look at the talks when you have some time.
The question
Anywho…that’s when my benchmarking and optimizing curiosity kicked in. It wasn’t until yet another talk at work concerning the benefits of an MVC framework (Symfony) that I started to think about Zend Framework and its performance out of the box (without caching). So I sat down today and started to benchmark the framework with a simple question in mind, “How does a simple ZF application compare to an application not using it?”
The applications
To answer the question I created 3 web projects. The first web project was a static-HTML only application which displayed “hello world” on the screen, very simple. (For those who just want to see the ab results click here as well as the Xdebug cachegrind output file.)
The second web project was a single PHP file with the below PHP code.
Finally, I replaced the default index.phtml HTML with the simple PHP code shown in Listing 1.1.
Yes some may say that these examples are far too simple, but I wanted to test the Framework’s process to load and what better way to do this than with a very simple example. I also based it off the talk that was given comparing Symfony.
The Hardware & ab command
Here is the set-up.
1. Windows machine running Apache 2.2
2. PHP 5.2.9
3. Zend Framework 1.8.4
4. Pentium 4 3.20 GHz
5. 1Gbs of RAM
I used the Apache Benchmark, ‘ab’, tool which comes included with all Apache installation and ran the below command 3 times.
Listing 1.3 > ab -n 1000 -c 5 http://localhost/index.[html|php]
The results, for me, were very surprising. I have included all the ab outputs.
Observations HTML ONLY – Reading 1
Concurrency Level: 5
Time taken for tests: 2.344 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 352000 bytes
HTML transferred: 83000 bytes
Requests per second: 426.67 [#/sec] (mean)
Time per request: 11.719 [ms] (mean)
Time per request: 2.344 [ms] (mean, across all concurrent requests)
Transfer rate: 146.67 [Kbytes/sec] received
HTML ONLY – Reading 2
Concurrency Level: 5
Time taken for tests: 2.375 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 352000 bytes
HTML transferred: 83000 bytes
Requests per second: 421.05 [#/sec] (mean)
Time per request: 11.875 [ms] (mean)
Time per request: 2.375 [ms] (mean, across all concurrent requests)
Transfer rate: 144.74 [Kbytes/sec] received
HTML ONLY – Reading 3
Concurrency Level: 5
Time taken for tests: 2.344 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 352000 bytes
HTML transferred: 83000 bytes
Requests per second: 426.67 [#/sec] (mean)
Time per request: 11.719 [ms] (mean)
Time per request: 2.344 [ms] (mean, across all concurrent requests)
Transfer rate: 146.67 [Kbytes/sec] received
Observations:
1. Roughly 0.0117 seconds per request.
2. Up to 424.79 requests satisfied per second.
Basic PHP – Reading 1
Concurrency Level: 5
Time taken for tests: 2.609 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 267000 bytes
HTML transferred: 81000 bytes
Requests per second: 383.23 [#/sec] (mean)
Time per request: 13.047 [ms] (mean)
Time per request: 2.609 [ms] (mean, across all concurrent requests)
Transfer rate: 99.93 [Kbytes/sec] received
Basic PHP – Reading 2
Concurrency Level: 5
Time taken for tests: 2.609 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 267000 bytes
HTML transferred: 81000 bytes
Requests per second: 383.23 [#/sec] (mean)
Time per request: 13.047 [ms] (mean)
Time per request: 2.609 [ms] (mean, across all concurrent requests)
Transfer rate: 99.93 [Kbytes/sec] received
Basic PHP – Reading 3
Concurrency Level: 5
Time taken for tests: 2.625 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 267000 bytes
HTML transferred: 81000 bytes
Requests per second: 380.95 [#/sec] (mean)
Time per request: 13.125 [ms] (mean)
Time per request: 2.625 [ms] (mean, across all concurrent requests)
Transfer rate: 99.33 [Kbytes/sec] received
Observations:
1. There seems to be a 100 request (roughly) drop when supporting PHP.
2. Requests per second satisfied = 382.47 (a drop of 42.32 requests or 9% drop)
3. Time per request = 13.073 or 0.0130 seconds per request (Increase of 11%)
Out of the box ZF 1.8.4 – Reading 1
Concurrency Level: 5
Time taken for tests: 68.297 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 197000 bytes
HTML transferred: 11000 bytes
Requests per second: 14.64 [#/sec] (mean)
Time per request: 341.484 [ms] (mean)
Time per request: 68.297 [ms] (mean, across a
Transfer rate: 2.82 [Kbytes/sec] received
Out of the box ZF 1.8.4 – Reading 2
Concurrency Level: 5
Time taken for tests: 70.281 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 197000 bytes
HTML transferred: 11000 bytes
Requests per second: 14.23 [#/sec] (mean)
Time per request: 351.406 [ms] (mean)
Time per request: 70.281 [ms] (mean, across all c
Transfer rate: 2.74 [Kbytes/sec] received
Out of the box ZF 1.8.4 – Reading 3
Concurrency Level: 5
Time taken for tests: 69.656 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 197000 bytes
HTML transferred: 11000 bytes
Requests per second: 14.36 [#/sec] (mean)
Time per request: 348.281 [ms] (mean)
Time per request: 69.656 [ms] (mean, across all c
Transfer rate: 2.76 [Kbytes/sec] received
Observations:
Framework not only has a slower response time but also satisfies less requests per second. Am I doing something wrong???? This cant be correct.
1. Request per second = 15.24 a change of 367.23 requests per second or a drop of 96% between trivial PHP and a ZF power app.
2. Time per request (time taken to satisfy 1 request) = 328.49 ms or 0.328 seconds a change of .315 seconds or an increase of 23%
Conclusion
Even though my benchmarking techniques might be flawed, taking a base line reading with no HTML as well as a very simple PHP script web project allowed me to at least compare.
Based on these figures (if correct) Zend Framework has a HUGE overheard. But this should not discourage any would be ZF coder because there are caching techniques which were not used such as using APC and the benefits of a good network admin
Also the benefits of using any framework far outweigh the drawbacks in my personal opinion. Where else can you get code which has been tested by the best and packed to contain methods for many of our typical coding requests.
I started to get the HTML5 itch a few weeks ago so I started to look around the web to feed my appetite for all things HTML 5. Turns out info is pretty hard to come by. Not sure when your reading this but its been tough to find adequate examples of what IS and what ISNT implemented yet since it all depends on the browser your using. Anyway. So im going to jot down my notes on using HTML5’s Web Database here by creating a few examples.
What is HTML 5.
HTML 5 is a collection of new tags, (list here) and along with the new tags it provides a tool set to store data on the user’s machine using javascript, yes Javascript (Web database API here).
What you need to get started.
For the example you’ll need at least Chrome 4. Of course you can use any browser you wish but YOU NEED TO BE SURE HTML 5 WEB DATABASE IS SUPPORTED.. I strongly recommend you download and install Google’s Chrome browser, so far it’s great. Click here for download link.
Thats all you need, oh! and you’ll need some HTML and Javascript know-how.
Figure 1.0 - Chrome Developer Tools
The tools
If you don’t have Chrome installed skip this section. This section will show the visual tool Chrome supplies developers to view not only the database but other neat things about your page.
Load the web page your going to test on. In my case its http://localhost then click on the “Control Page” document icon on the far-top-right corner of your browser . Select Developer > Developer Tools. (Figure 1.0)
You should now see a window as shown in Figure 1.2 (minus the DB). If you do not see the information displayed on Figure 1.2 click on “Storage” on the top menu. The “Storage” window contains a nice little DATABASE list on the left along with other items specific to that page. At the moment there’s no databases so you wont see anything. This is just the place where you’ll be able to work with the DB
How to create AND connect to the DB
Let’s create a database. Our database will have the name, “test_database” and will be our initial 1.0 version. (Note: the database name is case sensitive)
1. openDatabase(’name of db’, ‘version’, ‘database description’, total bits table will use, call back function)
The callback function is used to create the table structure if present. In this example we’ll create the tables later. Also note that the size of the database is dependent on the amount of free space the user has available.
Figure 1.2 Developer Tool Database
It is also recommended that the site only take up to 5 mbs of space. The spec also mentions the user will be prompted when the site requests additional space. (quote)
Once you run the above javascript on your sandbox, pull up the Chrome Developer tool, you should now see the database (Figure 1.2)
How to create a table.
Were going to add a table. We’re going open a connection to the database again as shown in the first example and then use the SQLTransation object to execute a CREATE statement.
dbObj = null;
function connectToDB()
{
dbObj = openDatabase('test_database', '1.0',
'Test Database', 1024*1024*3);
}
connectToDB();
//Create the table method
createTable = function()
{
dbObj.transaction(function(SQLTransaction){
SQLTransaction.executeSql(
"CREATE TABLE userinfo (id INTEGER PRIMARY KEY, item1 TEXT)", [],
function(){ alert('I am a successfull callback function!'); },
function(){ alert('Oh no! I am a sad error callback function'); } );
});
}
createTable();
Copy the above javascript, place into your file, and refresh the page. You will now have the table ‘userinfo’ in our database. If you want to add more tables simple call the method once more with a different CREATE statement. (Figure 1.3).
Some explaining…
SQLTransaction has 2 methods, transaction() (Read/Write) and readTransaction() (Read only). We use the transaction method when we need to read AND write. The readTransaction() has only ‘read only’ functionality and best used for SELECT SQL statements.
To execute the SQL statements we use the executeSql() method. A parameter explanation is shown below.
executeSql(’SQL Statement’, [], success callback function, error callback function) . The [] contains values for each ? used within the SQL statement. “INSERT INTO userinfo (item1) VALUES (?)” will replace the ? with the the content to save for the specific column. It’s also recommended to use this feature to code against SQL Injection attacks. (quote)
How to insert/update/delete records into the DB
At this point UPDATE, INSERT, as well as DELETE statements use the same process as the previous example. We use the SQLTransaction.transaction() method as well as the executeSql() method.
The next example will insert a record into our database table, ‘userinfo’, and we’ll verify the data entered using the Chrome Developer tool. Please note that the below code assumes you already created the table.
dbObj = null;
function connectToDB()
{
dbObj = openDatabase('test_database', '1.0',
'Test Database', 1024*1024*3);
}
connectToDB();
//Insert record into Table.
insertRecord = function(item1)
{
dbObj.transaction(function(SQLTransaction){
SQLTransaction.executeSql("INSERT INTO userinfo (item1) VALUES (?)", [item1],
function(){ alert('Record saved!'); },
function(){ alert('Uh Oh! record not save!'); } );
});
}
var item1 = "your not funny dude..really your not.";
insertRecord(item1);
Figure 1.3 - Verifying our record was inserted.
Pull up your Dev Tools Window again, expand the database by clicking the arrow, and click on the table. The record you just inserted will be displayed on the right as shown in Figure 1.3. Thats great but let’s now focus on retrieving the records to possibly manipulate the data!
How to List records
With data in our database, lets fetch the record we have in the table. To do so we use the read/write SQLTransaction method, readTransaction().
The following code assumes you have the database created, table created, and information stored in the table. If not go back and read the different sections.
In this example we query the table and display the results of the call. We use the SQLTransaction readTransaction() method, SQLTransaction executeSql() method passing in the SQL statement and a call back function displayRecords(). If the SQL SELECT statement successfully ran we pass a SQLResultSet object, ‘data’, to the displayRecords() method. The displayRecords() method fetches the HTMLElement node, ‘text’ and sets the text for the node to be the record fetched item1 value.
Fetching a specific value for a row.
To fetch the record we use the SQLResultSet object’s ‘rows’ attribute which returns a SQLResultSetRowList object. We then use the ‘item()’ method to fetch a specific row in the row list. In this case we fetch the first row and call the objects class property, ‘item1′. Note that each column in the table is represented but a class property.
Conclusion
We covered all the basic features of the HTML 5 web database. Inserting, creating a table, connecting to a DB, and fetching records. Give it a shot, if you have any questions feel free to leave a comment or refer to the W3C page
1. I had my yearly review last week..it went well
2. Ive been going on weekend hikes.
3. Ive been in an interesting mood lately.
4. Finals are this week.
5. Feel there are things better kept to myself.
6. Listening to Elton John.
7. Looking at purchasing a BMW 5 series within the. Maybe.
8. I’m breaking up with Subway today.
9. I didn’t get the job but at least be prof. and email back informing me that i didn’t.
10. Reliving my childhood through conversations is something i never though I could do.
Armando Padilla – 10 things i used to fill this post up since im not in the mood but have a lot on my mind.
I had one of those days today. Not good not bad, just a day. It was satisfying. Days like these i feel like the load on my back was removed and I can take a deep breath and calm down. I actually took a loooong deep breath, held it for a bit and then exhaled. It felt like i reached the top. Now im drinking a bit of wine, listening to Rob Thomas (it was playing on a local radio station coming home, so i wanted to listen to it again)
Today I won. Its not over yet but today I realized that I already won. Maybe that’s the reason why i feel like a huge load has been lifted off my shoulders.
Armando Padilla – looking at the battlefield i can see my results.
Do you think that we run in the way we live our life? I used to run a few laps in the opposite direction everyone else was running at the local park in South Gate when i lived in Los Angeles. Now, I run with my head down trying to finish my 2 miles. I look occasionally up to see how much i have left. .60 miles, 1.20 miles. 2 miles, *click the stop button. Just get it done.
I used to climb mountains in my dreams, a few nights ago I had a dream of climbing a mountain that I used to easily reach its summit, this time i took the harder route. The terrain wasn’t the issue it just had a casino, escalators, and generally people getting in my way. Beware of fluff.
2 teachers come to mind right now. One told my mom i had low self-esteem, the other told my mom I was a big fish in a small pond but I knew that already so I grow complacent. He warned me that one day I will be introduced to a bigger fish. Still thinking why this keeps bugging me.
I have a new friend that reminds me too much of an old friend. The body is different but the person is the same. We meet the same soul in this short journey many times throughout our lives for a reason. I’m not sure why.
I have 30 years to go, give or take. Going to make it count somehow.
Armando Padilla – Zoning out at work usually means im thinking of one of the 5 things above.