Zend Framework without mod_rewrite

Samstag, 05.02.2011 | PHP | 1 Kommentar | mod_rewrite , zend framework , php

For my hosting package, Apache mod_rewrite isn't enabled. As you can imagine it's not funny to use Zend Framework without it. With a little bit of coding it's possible to use the framework, anyway.

The first thing that we need is a own route. Rob Allen has created a route for URLs without mod_rewrite. This is a modified version of it

class My_Controller_Router_Route_RequestVars implements Zend_Controller_Router_Route_Interface
{
 protected $_current = array();

    /**
     * Instantiates route based on passed Zend_Config structure
     */
    public static function getInstance(Zend_Config $config)
    {
        return new self();
    }

    /**
     * Matches a user submitted path with a previously defined route.
     * Assigns and returns an array of defaults on a successful match.
     *
     * @param string Path used to match against this routing map
     * @return array|false An array of assigned values or a false on a mismatch
     */
    public function match($path)
    {
        $frontController = Zend_Controller_Front::getInstance();
        $request = $frontController->getRequest();
        /* @var $request Zend_Controller_Request_Http */
        
        $baseUrl = $request->getBaseUrl();
        if (strpos($baseUrl, 'index.php') !== false) {
            $url = str_replace('index.php', '', $baseUrl);
            $request->setBaseUrl($url);
        }
        
        $params = $request->getParams();
        
        if (array_key_exists('module', $params)
                || array_key_exists('controller', $params)
                || array_key_exists('action', $params)) {
            
            $module = $request->getParam('module', $frontController->getDefaultModule());
            $controller = $request->getParam('controller', $frontController->getDefaultControllerName());
            $action = $request->getParam('action', $frontController->getDefaultAction());

            $result = array('module' => $module, 
                'controller' => $controller, 
                'action' => $action, 
                );
            $this->_current = $result;
            return $result;
        }
        return false;
    }

    /**
     * Assembles a URL path defined by this route
     *
     * @param array An array of variable and value pairs used as parameters
     * @return string Route path with user submitted parameters
     */
    public function assemble($data = array(), $reset=false, $encode = false)
    {
        $frontController = Zend_Controller_Front::getInstance();
        
        if(!array_key_exists('module', $data) && !$reset 
            && array_key_exists('module', $this->_current)
            && $this->_current['module'] != $frontController->getDefaultModule()) {
            $data = array_merge(array('module'=>$this->_current['module']), $data);
        }
        if(!array_key_exists('controller', $data) && !$reset 
            && array_key_exists('controller', $this->_current) 
            && $this->_current['controller'] != $frontController->getDefaultControllerName()) {
            $data = array_merge(array('controller'=>$this->_current['controller']), $data);
        }
        if(!array_key_exists('action', $data) && !$reset 
            && array_key_exists('action', $this->_current)
            && $this->_current['action'] != $frontController->getDefaultAction()) {
            $data = array_merge(array('action'=>$this->_current['action']), $data);
        }
        
        $url = '';
        if(!empty($data)) {
            $url = '?' . http_build_query($data, '', '&');
        }

        return $url;
    }
}

To add this route, we need to tell the router about it in our index.php like this:

$bootstrap->bootstrap('frontController');
$front = $bootstrap->frontController;
$router = $front->getRouter();
$router->addRoute('requestVars', new My_Controller_Router_Route_RequestVars());

Second thing we need is a URL view helper that is used instead of Zend Frameworks URL view helper.

/**
 * URL view helper
 * 
 * @category   My
 * @package    My_View
 * @subpackage Helper
 * @author Burak Yueksel
 * @copyright Copyright (c) 2010 Burak Yueksel
 *
 */
class My_View_Helper_Url extends Zend_View_Helper_Abstract
{
	public function url(array $urlOptions = array(), $numericPrefix='', $argSeparator='&')
	{
		$request = Zend_Controller_Front::getInstance()->getRequest();
		
		if(!isset($urlOptions['module'])) $urlOptions['module'] = $request->getModuleName();
		if(!isset($urlOptions['controller'])) $urlOptions['controller'] = $request->getControllerName();
		if(!isset($urlOptions['action'])) $urlOptions['action'] = $request->getActionName();
		 
		$hyperLink = '/?module='.$urlOptions['module'].$argSeparator;
		$hyperLink .= 'controller='.$urlOptions['controller'].$argSeparator;
		$hyperLink .= 'action='.$urlOptions['action'].$argSeparator;
		
		unset(
			$urlOptions['module'], 
			$urlOptions['controller'], 
			$urlOptions['action']
		);
		
		if(sizeof($urlOptions)) {
			$hyperLink .= http_build_query($urlOptions, $numericPrefix, $argSeparator);	
		}
		return $hyperLink;
	}
}

This view helper will create URLs like this

/?module=index&controller=index&action=whatever&param1=hello&param2=world

This also works with Zends URL view helper but only if you reqeust the website with /?controller=index.

Now we need to add configuration for our own view helper to application.ini

resources.view.helperPath.My_View_Helper = APPLICATION_PATH "/../library/My/View/Helper"

Thats it! Now we're able to build websites using Zend Framework without mod_rewrite.

Share


1 Comments

 

Montag, 28.03.2011, 00:05

You just saved my day today :) Thank you for sharing that router, it's exactly what I was looking for, thank you! :)