Ashish Ranjan Ashish Ranjan - 13 hours ago 2
PHP Question

How to have "dashes" in filenames in ZendFramework 1.12

I have seen a few posts regarding this question but none were answered to the topic on which they were asked. I have a ZendFramework project (v 1.12) and I want to do some changes in the file naming conventions.

The files and folders are named in Pascal case and I want to make the following changes:


  1. rename all the files/folders to lowercase (this works)

  2. I want dashes (
    "-"
    ) in between words. The Zend maual says that dashes could be there in the file names. But then again says that they should be mapped to the class names, (A Class Name cannot contain a
    -
    !!). And now there is
    Zend Router
    , it translates the
    -
    in URL and joins the words in between them back to the Pascal case. How do I manipulate that?



For example, Here is a file name:
TestingDemoController.php
, I want to change the name as
testing-democontroller.php
(actually I was thinking of making it as
testing-demo.controller.php
but don't know how possible is it.) For the previous filename, the
URI
used to be something like
Testing-Demo
. How can the router be configured to not treat
-
as a special character?


Edit: Questions on PSR:


On the suggestion of @apokryfos, I have been reading through PSR releases, PSR-0 and PSR-4 mostly.


  • looking at my class names (directories separated with underscore until the Terminating class name) I feel that we have used PSR-0 in our project.

  • On my approach to the change in project structure (having dashes in between file names). This goes against PSR-4,




The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name.


Is the above point, the only point which I am going against?


  • This is what I feel about the ramifications that can happen on me doing the file name (dashed) and writing my own
    autoloader
    :
    When looking for the files in
    libraries
    , the files will be looked by my autoloader, the search will fallback to the Standard Autoloader which will finally resolve them? This is leading to unnecessary lookups.



Please correct me here if I am understanding it wrong and if am missing something?

Answer

I have done this for a project once.

There are 2 things that need to be done for this to work:

Override Zend Dispatcher

In order to override the standard Zend Dispatcher, create a file called Custom.php under "Zend/Controller/Dispatcher" with contents:

<?php

class Zend_Controller_Dispatcher_Custom extends Zend_Controller_Dispatcher_Standard {

    const DELIMITER = '-';
    public function classToFilename($class)
    {
        $class = trim(strtolower(preg_replace('/([A-Z]+)/', self::DELIMITER . "$1", $class)), self::DELIMITER); //str_replace('Controller', '-controller', $class);
        return str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
    }

}

and in your Bootstrap.php of your application path, add this function:

protected function _initControllerDirectoryPath()
    {
            $frontController = Zend_Controller_Front::getInstance();
            $frontController->setDispatcher(new Zend_Controller_Dispatcher_Custom());
    }

This way you will get controllers with a - to be found, eg demo-controller.php. In this case, you will have to change all controllers to the new formats.

Override module resource loader

This is tricky, as you need to define your own autoloader. Create a file "MyAutoloader.php" under "Zend/Loader" and add the following code:

<?php
class Zend_Loader_MyAutoloader extends Zend_Application_Module_Autoloader {

    public function autoload($class)
    {
        $classParts = explode('_', $class);
        $classParts[count($classParts) - 1] = trim(strtolower(preg_replace('/([^_])([A-Z]+)/', "$1-$2", end($classParts))), '-');
        $class = implode('_', $classParts);
        $classPath = $this->getClassPath($class);
        if (false !== $classPath) {
            return include $classPath;
        }
        return false;
    }
}

and in each module Bootstrap.php, you will need to add:

class Mymodule_Bootstrap extends Zend_Application_Module_Bootstrap
{
    public function __construct($application)
    {
        parent::__construct($application);

        $r    = new ReflectionClass($this);
        $path = $r->getFileName();
        $this->setResourceLoader(new Zend_Loader_MyAutoloader(array(
            'namespace' => $this->getModuleName(),
            'basePath'  => dirname($path),
        )));
    }
}

This will enable to use also module resources eg. "modules/mymodulename/forms/search-test.php"

If you use shared resources, eg forms, models etc, then you also need to register Zend_Loader_MyAutoloader for these in your main Bootstrap by adding:

protected function _initResourcesDirectoryPath()
{
    $loader = new Zend_Loader_MyAutoloader(array(
                'basePath'  => dirname(__FILE__),
                'namespace' => '',
    ));
}

Now you can have a file eg forms/test-shared-search.php Note that class names remain the same inside the files(eg Form_TestSharedSearch in the last case)