Monday, January 12, 2009

Mysql Optimization - schema optimization

1. Choose optimal data type
a. smaller is better - less space on disk, in memory, in CPU cache
b. simple is good (use integer instead of ip address, for example);
c. avoid null if possible - null requires special processing, makes index, comparisons more complicated.

2.Index strategies
a. isolate the column. mysql can't use index unless the columns are isolated in query
e.g., suppose id is primary key.
select * from test where id+1 = 5; should be changed to select * from test where id = 4

b. Prefix index
e.g., if u need to index long character columns, index the first few characters
alter table test add key (long_name(5));
downside is prefix index cannot be used for order by or group by

c. covering indexex
e.g. an index containing all the data needed for a query is covering index
-index entries are smaller and faster than row size
-indexes are sorted by their values

Normalization and Denormalization
A mixture of Normalized and Denormalized

Thursday, January 8, 2009

Zend framework Zend_Acl

Acl stands for action control list.

The typical flow for using Zend_Acl in a web application is as follows:
1. Instantiate the Zend_Acl class (let’s call this object $acl).
2. Add one or more roles to $acl using the addRole() method.
3. Add resources to $acl using the add() method.
4. Add the full list of privileges for each role (that is, use allow() or deny() to indicate which resources roles have access to).
5. Use the isAllowed() method on $acl to determine whether a particular role has access
to a particular resource/privilege combination.
6. Repeat step 5 as often as necessary while the script executes.

Example:
$this->auth = $auth;
$this->acl = new Zend_Acl();
//add the different user role
$this->acl->addRole(new Zend_Acl_Role($this->_defaultRole));
$this->acl->addRole(new Zend_Acl_Role('admin'));
$this->acl->addRole(new Zend_Acl_Role('member'));
$this->acl->addRole(new Zend_Acl_Role('administrator'), 'member');
// add the resources we want to have control over
$this->acl->add(new Zend_Acl_Resource('account'));
$this->acl->add(new Zend_Acl_Resource('admin'));

// allow access to everything for all users by default
// except for the account management and administration areas
$this->acl->allow();
$this->acl->deny(null, 'account');
$this->acl->deny(null, 'admin');
// add an exception so guests can log in or register
// in order to gain privilege
$this->acl->allow('guest', 'account', array('login', 'fetchpassword' , 'register' , 'registercomplete'));
// allow members access to the account management area
$this->acl->allow('member', 'account');
$this->acl->allow('admin', 'admin');

public function preDispatch (Zend_Controller_Request_Abstract $request)
{
// check if a user is logged in and has a valid role,
// otherwise, assign them the default role (guest)
if ($this->auth->hasIdentity()) {
$role = $this->auth->getIdentity()->subscription_type;
} else {
$role = $this->_defaultRole;
}
if (! $this->acl->hasRole($role)) {
$role = $this->_defaultRole;
}
// the ACL resource is the requested controller name
$resource = $request->controller;
// the ACL privilege is the requested action name
$privilege = $request->action;
// if we haven't explicitly added the resource, check
// the default global permissions
if (! $this->acl->has($resource))
$resource = null;
// access denied - reroute the request to the default action handler
if (! $this->acl->isAllowed($role, $resource, $privilege)) {
$request->setControllerName($this->_authController['controller']);
$request->setActionName($this->_authController['action']);
}
}

in bootstrap file, we add
$frontController->registerPlugin(new ControllerAclManager($auth));

Wednesday, January 7, 2009

Zend framework Zend_Auth

We can use Zend_Auth to process user authentication.

$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) { //user already login
$this->_redirect(/*redirect url*/);
}

$request = $this->getRequest();
if ($request->isPost()) {
$username = trim($request->getPost('username'));
$password = trim($request->getPost('password'));
//below is the key part of authentication
//$this->db must be a db adapter
$adapter = new Zend_Auth_Adapter_DbTable($this->db, 'username', 'password', 'md5(?)');
$adapter->setIdentity($username);
$adapter->setCredential($password);
$result = $auth->authenticate($adapter);
if ($result->isValid()) { //login successful
$auth->getStorage()->write($identity); //save itentity
//redirect
} else {//login failed

}
}

logout is simple as well: Zend_Auth::getInstance()->clearIdentity(); That is it.

Monday, January 5, 2009

Superficial impression of Zend Framework

It is huge, compared with other frameworks such as CakePHP or CodeIgnitor.

You can use it as a library without following its MVC architecture design. For example, Zend_Validate class family can save you a lot of work on input validation.

Naturally, huge framework comes with huge document - Programmer's reference guide.

Sometimes you need to head into the source code to figure out what really happened.

Despite its huge size, I think it is still easy to learn, although it may not be easier than any other frameworks.

Sunday, January 4, 2009

Integrate Smarty with Zend Framework

I collected some information regarding this topic.

The first one is probably the easiest approach to use Smarty in Zend framework.
require('Zend.php');

include 'smarty/Smarty.class.php';
$smarty = new Smarty();
$smarty->template_dir = 'resources/templates';
$smarty->compile_dir = 'resources/templates_c';
$smarty->plugins_dir = array(SMARTY_DIR . 'plugins', 'resources/plugins');
//may be some more smarty setup

//register this smarty
Zend::register('smarty', $smarty);

//use it in action controller
class IndexController extends Zend_Controller_Action
{
function index()
{
$smarty = Zend::registry('smarty');
$smarty->assign('title', 'Test');
$smarty->display('index.tpl');
}
}

However, you have to handle view logic in your action controllers.

The second option is to extend Zend_View_Abstract
class Templater extends Zend_View_Abstract
{
protected $_path;
protected $_engine;

public function __construct()
{
$config = Zend_Registry::get('config');

require_once('Smarty/Smarty.class.php');

$this->_engine = new Smarty();
$this->_engine->template_dir = $config->paths->templates;
$this->_engine->compile_dir = sprintf('%s/tmp/templates_c',
$config->paths->data);

$this->_engine->plugins_dir = array($config->paths->base .
'/include/Templater/plugins',
'plugins');
}

public function getEngine()
{
return $this->_engine;
}

public function __set($key, $val)
{
$this->_engine->assign($key, $val);
}

public function __get($key)
{
return $this->_engine->get_template_vars($key);
}

public function __isset($key)
{
return $this->_engine->get_template_vars($key) !== null;
}

public function __unset($key)
{
$this->_engine->clear_assign($key);
}

public function assign($spec, $value = null)
{
if (is_array($spec)) {
$this->_engine->assign($spec);
return;
}

$this->_engine->assign($spec, $value);
}

public function clearVars()
{
$this->_engine->clear_all_assign();
}

public function render($name)
{
return $this->_engine->fetch(strtolower($name));
}

public function _run()
{ }
}
And we need to set up view renderer in bootstrap file
// setup the view renderer
$vr = new Zend_Controller_Action_Helper_ViewRenderer();
$vr->setView(new Templater());
$vr->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($vr);

An alternative is to implement Zend_View_Interface
class App_View implements Zend_View_Interface
{
/**
* Smarty object
* @var Smarty
*/
protected $_smarty;

/**
* Constructor
*
* @param string $tmplPath
* @param array $extraParams
* @return void
*/
public function __construct($tmplPath = null, $extraParams = array())
{
require_once ('Smarty/Smarty.class.php');
$this->_smarty = new Smarty;

if (null !== $tmplPath) {
$this->setScriptPath($tmplPath);
}

foreach ($extraParams as $key => $value) {
$this->_smarty->$key = $value;
}
$config = Zend_Registry::get('config');
$this->_smarty->compile_dir = sprintf('%s/templates_c', $config->paths->data);
$this->_smarty->plugins_dir = '';
$this->base_url = $config->paths->baseurl;
}

/**
* Return the template engine object
*
* @return Smarty
*/
public function getEngine()
{
return $this->_smarty;
}

/**
* Set the path to the templates
*
* @param string $path The directory to set as the path.
* @return void
*/
public function setScriptPath($path)
{
if (is_readable($path)) {
$this->_smarty->template_dir = $path;
return;
}

throw new Exception('Invalid path provided');
}

/**
* Retrieve the current template directory
*
* @return string
*/
public function getScriptPaths()
{
return array($this->_smarty->template_dir);
}

/**
* Alias for setScriptPath
*
* @param string $path
* @param string $prefix Unused
* @return void
*/
public function setBasePath($path, $prefix = 'Zend_View')
{
return $this->setScriptPath($path);
}

/**
* Alias for setScriptPath
*
* @param string $path
* @param string $prefix Unused
* @return void
*/
public function addBasePath($path, $prefix = 'Zend_View')
{
return $this->setScriptPath($path);
}

/**
* Assign a variable to the template
*
* @param string $key The variable name.
* @param mixed $val The variable value.
* @return void
*/
public function __set($key, $val)
{
$this->_smarty->assign($key, $val);
}

/**
* Retrieve an assigned variable
*
* @param string $key The variable name.
* @return mixed The variable value.
*/
public function __get($key)
{
return $this->_smarty->get_template_vars($key);
}

/**
* Allows testing with empty() and isset() to work
*
* @param string $key
* @return boolean
*/
public function __isset($key)
{
return (null !== $this->_smarty->get_template_vars($key));
}

/**
* Allows unset() on object properties to work
*
* @param string $key
* @return void
*/
public function __unset($key)
{
$this->_smarty->clear_assign($key);
}

/**
* Assign variables to the template
*
* Allows setting a specific key to the specified value, OR passing
* an array of key => value pairs to set en masse.
*
* @see __set()
* @param string|array $spec The assignment strategy to use (key or
* array of key => value pairs)
* @param mixed $value (Optional) If assigning a named variable,
* use this as the value.
* @return void
*/
public function assign($spec, $value = null)
{
if (is_array($spec)) {
$this->_smarty->assign($spec);
return;
}

$this->_smarty->assign($spec, $value);
}

/**
* Clear all assigned variables
*
* Clears all variables assigned to Zend_View either via
* {@link assign()} or property overloading
* ({@link __get()}/{@link __set()}).
*
* @return void
*/
public function clearVars()
{
$this->_smarty->clear_all_assign();
}

/**
* Processes a template and returns the output.
*
* @param string $name The template to process.
* @return string The output.
*/
public function render($name)
{
return $this->_smarty->fetch($name);
}

/**
* get smarty template dir
*
* @return string template dir
*/
public function getScriptPath()
{
return $this->_smarty->template_dir;
}//end getScriptPath()
}


There is one problem with this method: all template files have to be placed in one directory. What if we want to put template files in different folders? Say, i have two modules, and their templates are placed in two folders named with the module names?

The key is the value of template_dir. To work around, we can specify template_dir at action controller.

class App_ControllerAction extends Zend_Controller_Action
{
public $db;
public function init()
{
//set smarty templete dir
$module = $this->getRequest()->getModuleName();
$path = Zend_Registry::get('config')->paths->templates;
if (empty($module) === false) {
$this->view->setScriptPath($path . '/' . $module);
}
}
}

Share two FREE books download websites

http://www.ebookee.com/

http://www.pdfchm.net/

The second website specializes in IT books. I am not sure if they are legal but, hey, they are there and you do can download books from them. And these books may cost you hundreds of bucks if you buy the print version from amazon or any book stores.