Beach Blogger

Saturday, March 22, 2008

Zend Framework 1.5 Migration: Clarification of camelCase changes

Did your upgrade to Zend Framework 1.5 break due to camelCase stuff?

Zend Framework 1.5 migration was not without some problems for me (personally, I had MixedCase which also had problems).

They changed the Zend_Controller rules for mapping URLs to view action functions.

Although the migration is described in the documentation at http://framework.zend.com/manual/en/zend.controller.migration.html#zend.controller.migration.fromoneohtoonefive the description it's not very easy to understand.

A short and clear explanation is at: http://www.nabble.com/AW%3A-Normalizing-action-function-names-p16110540s16154.html

Echos of some of the "surprise" that was felt when developers realized what was done is at: http://www.nabble.com/Re%3A-Normalizing-action-function-names-p16156586s16154.html

(adding this alternate link to the docs for search engines http://framework.zend.com/manual/en/zend.controller.migration.html )

Friday, November 09, 2007

Zend Framework and HTML_QuickForm_Controller for Multiple Page Forms

For generating generic forms in Zend Framework,
zend_controller and HTML_QuickForm integration is shown at:

http://blog.case.edu/gps10/2006/03/17/using_zend_framework_smarty_and_quickform_to_quickly_deploy_php_applications


In addition to using html_quickform in zend framework, I wanted multiple page forms via HTML_QuickForm_Controller.

(yes, I can implement multi-page forms in zend_controller but this pear package has already done it for me so why not use it?).

I got a tip on setting attributes from
http://news.php.net/php.pear.general/28170




I did get it to work, but I wouldn't say I understand it...

Two things need changing:

-set 'action' attribute in 2 places

-Set action to current page url without the get parameters




It works, but it's pretty slow. Comparing it to the 'raw' version that runs outside zend framework (on the same machine), the zend framework version takes twice (from 2x to 2.5x) the time to respond. The slow Windows file system is likely to blame (see http://www.nabble.com/RE%3A-ZF-performance-advice-p13268859s16154.html ), but I don't know how much speed-up I can get on a linux box. It would be great to get some performance numbers from http://www.nabble.com/Re%3A-ZF-performance-advice-p13185506s16154.html

11/18/07 Update: I just saw this post: http://www.nabble.com/RE%3A-ZF-performance-advice-p13285168s16154.html which makes me more comfortable with this approach on a server class computer and OS.




I used the wizard.php example from html_quickform_controller examples.

The sample code is available for download at:

http://www.nabble.com/Zend-Framework-and-HTML_QuickForm_Controller-for-Multiple-Page-Forms-p13679900s16154.html

and is shown here (the embedded pre tag and php tag need adjusting):








< ? php /** * testing html_quickform_controller with zend framework * * based on wizard.php example from html_quickform_controller * * @author Dennis Fogg */ /** *********************************************************************** * qf controller for zend framework mvc * * *********************************************************************** */ class qfController extends Zend_Controller_Action { /** * html_quickform_controller test * * based on: http://blog.case.edu/gps10/2006/03/17/using_zend_framework_smarty_and_quickform_to_quickly_deploy_php_applications * * * i need a separate controller here because just making it * an action * failed when i tried it. * i think it's because of the extra classes read in. * */ /** * strip out get parameters from a url * * @param unknown_type $url * @return unknown */ public static function strip_get_params($url) { $pos = strpos($url, '?'); $sub = substr($url, 0, $pos); //print "$sub"; return $sub; } public function MultiplePageAction() { set_include_path( get_include_path() ); /** * Example 2 for HTML_QuickForm_Controller: Wizard * * @version CVS: $Id: wizard.php,v 1.3 2007/05/18 09:34:18 avb Exp $ * @author Alexey Borzov
* @ignore
*/

require_once 'Controller.php';

// Load some default action handlers
require_once 'Action/Next.php';
require_once 'Action/Back.php';
require_once 'Action/Jump.php';
require_once 'Action/Display.php';

// Start the session, form-page values will be kept there
session_start();


$wizard =& new HTML_QuickForm_Controller('Wizard');



// zf: replace these
/*$wizard->addPage(new PageFirst('page1'));
$wizard->addPage(new PageSecond('page2'));
$wizard->addPage(new PageThird('page3'));*/


/**
* zf: changes
* assign using =& instead of = for the new
* i don't know why, but not using it causes problems even though i'm in php5
*
*/
$a_page =& new PageFirst('page1');
$a_page->setAttribute('action', qfController::strip_get_params(get_page_url()));
$wizard->addPage($a_page);

$a_page =& new PageSecond('page2');
$a_page->setAttribute('action', qfController::strip_get_params(get_page_url()));
$wizard->addPage($a_page);

$a_page =& new PageThird('page3');
$a_page->setAttribute('action', qfController::strip_get_params(get_page_url()));
$wizard->addPage($a_page);






// We actually add these handlers here for the sake of example
// They can be automatically loaded and added by the controller
$wizard->addAction('display', new HTML_QuickForm_Action_Display());
$wizard->addAction('next', new HTML_QuickForm_Action_Next());
$wizard->addAction('back', new HTML_QuickForm_Action_Back());
$wizard->addAction('jump', new HTML_QuickForm_Action_Jump());

// This is the action we should always define ourselves
$wizard->addAction('process', new ActionProcess());

$wizard->run();



}

}



class PageFirst extends HTML_QuickForm_Page
{
function buildForm()
{
$this->_formBuilt = true;

$this->addElement('header', null, 'Wizard page 1 of 3');

$radio[] = &$this->createElement('radio', null, null, 'Yes', 'Y');
$radio[] = &$this->createElement('radio', null, null, 'No', 'N');
$this->addGroup($radio, 'iradYesNo', 'Are you absolutely sure?');

$this->addElement('submit', $this->getButtonName('next'), 'Next >>');

$this->addRule('iradYesNo', 'Check Yes or No', 'required');

$this->setDefaultAction('next');


// zf: trying to get 'current page' set correctly for zf
$this->setAttribute('action', qfController::strip_get_params(get_page_url()));
}
}

class PageSecond extends HTML_QuickForm_Page
{
function buildForm()
{
$this->_formBuilt = true;

$this->addElement('header', null, 'Wizard page 2 of 3');

$name['last'] = &$this->createElement('text', 'last', null, array('size' => 30));
$name['first'] = &$this->createElement('text', 'first', null, array('size' => 20));
$this->addGroup($name, 'name', 'Name (last, first):', ', ');

$prevnext[] =& $this->createElement('submit', $this->getButtonName('back'), '<<>createElement('submit', $this->getButtonName('next'), 'Next >>');
$this->addGroup($prevnext, null, '', ' ', false);

$this->addGroupRule('name', array('last' => array(array('Last name is required', 'required'))));

$this->setDefaultAction('next');


// zf: trying to get 'current page' set correctly for zf
$this->setAttribute('action', qfController::strip_get_params(get_page_url()));

}
}

class PageThird extends HTML_QuickForm_Page
{
function buildForm()
{
$this->_formBuilt = true;

$this->addElement('header', null, 'Wizard page 3 of 3');

$this->addElement('textarea', 'itxaTest', 'Parting words:', array('rows' => 5, 'cols' => 40));

$prevnext[] =& $this->createElement('submit', $this->getButtonName('back'), '<<>createElement('submit', $this->getButtonName('next'), 'Finish');
$this->addGroup($prevnext, null, '', ' ', false);

$this->addRule('itxaTest', 'Say something!', 'required');

$this->setDefaultAction('next');


// zf: trying to get 'current page' set correctly for zf
$this->setAttribute('action', qfController::strip_get_params(get_page_url()));

}
}



class ActionProcess extends HTML_QuickForm_Action
{
function perform(&$page, $actionName)
{
echo "Submit successful!
\n<>\n";
var_dump($page->controller->exportValues());
echo "\n\n";

// zf: destroy session
$_SESSION = array();
session_destroy();
}
}


Wednesday, October 17, 2007

PHP Performance Improvements

Summary:
My Zend framework page generation time went from 1.2 sec to 0.4 sec using a number of techniques. I compare my performance with Rob Allen's tutorial code (which has minimal excess code -- being a tutorial). Allen's code also runs at 0.4 sec (http://www.nabble.com/Re%3A-ZF-performance-advice-p13185506s16154.html), so my ZF infrastructure has negligible overhead now.

It did not start out that way. It started out slow at 1.2 sec.

I looked at techniques from http://ilia.ws/files/frankfurt_perf.pdf and some from http://talks.php.net/show/ezkey06

My setup: my laptop is the web server: 1.2 gb ram, 1.6 ghz single core, 7200 rpm disk, Windows XP, php 5.2.3, Apache 2.2.4, postgres 8.2, Zend Framework 1.0.2 and I used a different PC as my browser client.

I'm testing the performance of a web page that just has a few words on it. It also does a Smarty include of a header page with a few words. The PHP script does connect to my db.

It's hard to track down the time culprut. Time floats from one section to another when I try to narrow down slow sections. Yet the overall time is somewhat consistent. I switched to mysql db for timing purposes because the times were more consistent and the connection time was smaller so other performance times would not be masked by the db connect.

What code changes did I implement?
  • combine classes into 1 file so fewer files are require / include
  • use full path or at least a relative path for require / include for files.
  • Prune include path to be only essential directories (eg: top level directory)
  • Less less impact but i implemented: Avoid instantiating a feature rich class. Eg: zend_log: put a wrapper so that I only instantiates it if I use it – was a bit tricky since there are log filters too

i also got a significant speed improvement by moving my code under the apache root (rather than being on a different partition on my hard drive).

this got me down to about .6 - .7 sec.

now the "interesting" part: if i restart apache and run my page first, it runs fast (.4 sec). In fact, the Allen tutorial runs at .6 sec if it's loaded after my page. restart apache and run them in the different order and the speeds will be swapped... Something funky is going on (cache size?).

well, the code is fast enough to start development on top of it.

Future coding for performance:

  • Only use modules/building blocks that I really need. Fancy features will cost me time. eg: zend_config is powerful but: file read and parse were taking time, but even accessing the config parameters were taking significant time according to cachegrind.

looking at cachegrind via wincachegrind, i see that file loading is still taking a approx 1/3 of the total time!! this is even with opcode caching. Most of this is ZF file loading! i'll have to look at the best way to load files when i get to my production platform. This does suggest a possible performance improvement: have a "packed version" of the zend framework that combines classes into fewer files -- this would improve performance on every ZF script execution and be of no detriment!

3/22/08 update: see important performance notes about the Windows OS file system in my later post at http://beach-blogger.blogspot.com/2007/11/zend-framework-and-htmlquickformcontrol.html

Friday, September 14, 2007

Zend Framework: Postgres vs MySQL connection times

10/15/07 update: On persistent connections, see http://us2.php.net/manual/en/function.pg-pconnect.php#78476 As a correction to this post and on db connection speed, see http://www.nabble.com/Re%3A-ZF-performance-advice-p13186947s16154.html


Abstract: Postgres is my preferred db but it’s running slow; should I use MySQL instead?
Answer: Nope, Postgres can be made to connect just as fast as MySQL with a small change supported by the Zend Framework’s Zend_Db.

Good news: I got my ZF Postgres db connection up and running
Bad news: it was taking 1.5 seconds just for my zf bootstrap environment to run with no db queries.

I was concerned: maybe Postgres is too slow and I should use MySQL.
So I did a little study.
The result: I got Postgres connections to be just as fast as MySQL by using persistent connections.


My setup:

Laptop: 1.2 gb ram, 1.6 ghz single core, 7200 rpm disk, Windows XP


Php 5.2
Postgres 8.2
Apache 2.2
Firefox 2.0


No query; just connect to db using Zend_Db: $db->getConnection();

With about 10 samples:

Postgres:
0.7 - 0.9 sec with occassional peaks of 1.2 sec for 1 db connect
1.4 – 1.6 sec for 2 db connects to the same db.

MySQL:
0.6 - 0.7 sec for 1 db connect
1.1 – 1.2 sec for 2 db connects to the same db.


Now, add persistent connections via:

$driver_options = array(PDO::ATTR_PERSISTENT => true);


Postgres:
0.6 - 0.6 sec with occassional peaks of 0.8 sec for 1 db connect
1.1 – 1.2 sec for 2 db connects to the same db.

So it’s working and speeding connections up!

MySQL:
0.6 - 0.7 sec for 1 db connect
1.1 – 1.2 sec for 2 db connects to the same db.

No difference…
Does not seem to be working

Postgres is just as fast as MySQL for connections now!
So, switching to MySQL won’t help.
But the whole thing is still pretty slow…

I wonder if pgpool would help.
Anyone have any advice on pgpool?

Thursday, August 30, 2007

Zend Framework and Smarty Integration Tips

Just got Zend Framework 1.0.1 and Smarty to work together!!!


ain't that easy...


here's what i did:







    here's the code in my bootstrap:

    // Different view implementation
    //$view = new ZF_Smarty();
    $smarty_config = array(
    'compile_dir' => './smarty/templates_c/',
    'config_dir' => './smarty/configs/',
    'cache_dir' => './smarty/cache/',
    'debugging' => true,
    );
    $view = new Zend_View_Smarty('./application/views/scripts/', $smarty_config);

    $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
    $viewRenderer->setViewBasePathSpec('./application/views/scripts/')
    ->setViewScriptPathSpec(':controller'.DIRECTORY_SEPARATOR.':action.:suffix')
    ->setViewScriptPathNoControllerSpec(':action.:suffix')
    ->setViewSuffix('tpl');
    Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);




Friday, March 23, 2007

blogsticker

7abdbb51b7596e9baa31bf87316f4fee

is this a friendly way to confirm blog ownership or what??

Monday, February 26, 2007

php dir structure

some info on dir structure:

http://zft.backupdiy.com/2006/12/22/file-structure-redesign-2/

http://framework.zend.com/wiki/display/ZFDEV/Choosing+Your+Application%27s+Directory+Layout



and here's on on auth and acl:

http://devzone.zend.com/node/view/id/1665

About Me

I'm a web dude and this is my geek blog. There should be lots of content ... if I'm working hard ...