1

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, on failure 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?

Ashish Ranjan
  • 12,760
  • 5
  • 27
  • 51
  • 2
    For what it's worth, what you're doing goes against [PSR-4](http://www.php-fig.org/psr/psr-4/) which is a PHP coding standard you should be following. – apokryfos Jul 13 '17 at 12:38
  • Okay thanks, trying to understand it.. – Ashish Ranjan Jul 14 '17 at 05:37
  • @apokryfos: I have updated the question, can please give some of your inputs regarding my understanding of PSR there? – Ashish Ranjan Jul 17 '17 at 14:25
  • 2
    The only ramification of going against the PSR-0/4 auto-loading standards is that you have to implement the autoloading yourself instead of using one of the many existing PSR-0 or PSR-4 compliant autoloaders. You will also be unable to convert your project into a more modular structure without bundling your own auto-loader as a dependency for each module. – apokryfos Jul 17 '17 at 15:42
  • Got it, while I will have a look at it myself, but can you say if I am correct on saying, that while loading library files, it will fallback to the standard autoloader causing unnecessary lookups? – Ashish Ranjan Jul 17 '17 at 16:57
  • Well, if you have 2 autoloaders then that will happen, in practice the overhead of autoloading is minimal so not something that should be a big concern. – apokryfos Jul 18 '17 at 05:55
  • Okay, thank you :) – Ashish Ranjan Jul 18 '17 at 06:43

2 Answers2

2

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)

baikho
  • 5,203
  • 4
  • 40
  • 47
Jannes Botis
  • 11,154
  • 3
  • 21
  • 39
  • Great, I was myself looking through all the docs and sources, thanks for the detailed answer. I don't have my code with me now but will certainly let you by tomorrow about how it goes. – Ashish Ranjan Jul 14 '17 at 17:55
  • The only thing I am hesitating is to create files in Zend Library itself. Can't I override the functionalities in my application itself? Anyway, I will have a look tomorrow. – Ashish Ranjan Jul 14 '17 at 18:12
  • Actually you do not have to create the files in the zend library itself. You can name the classes eg Mylibrary_MyAutoloader and Mylibrary_Dispatcher_Custom, place them under Mylibrary directory and register this new library using registerNamespace() of the autoloader. – Jannes Botis Jul 14 '17 at 18:46
  • Many thanks, although I am having a few problems, but now I know how to proceed. Great solution :) – Ashish Ranjan Jul 15 '17 at 10:09
  • With shared resources, did you mean models, forms etc which are not under a specific module? And I guess you missed `$this->setResourceLoader($loader)` for the Shared Resources. And also do you know any good links for understanding Routing, usage of both the Rest Controllers and normal Zend Action Controllers? (other than the Zend Manual) – Ashish Ranjan Jul 16 '17 at 08:06
  • Yes, that is what I mean. And yes, maybe I missed a couple of things. Xm, I am not sure about resources, cannot think of something – Jannes Botis Jul 16 '17 at 09:52
0

You can do that, but then you either need to use spl_autoload_register to create your own autoloader or include/require manually. Also, even though that is going to help with your file names, class names won't change, and you will definitely to have a custom routing.

That said, apokryfos is definitely right about PSR-4.

Thomas Dutrion
  • 1,844
  • 1
  • 11
  • 9