SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Zend Framework "killing" Apache on Windows

    Hi folks,

    I'm doing my first steps in Zend Framework.
    Read/heard much about it and wanted to give it a chance before developing my current project "as usual".

    My problem: if I request a module/controller/action that isn't implemented yet my apache takes the systems load to 50% - on a dual core AMD!
    The request never dies, it keeps loading and loading.
    I would expect that it looks for the requested module, controller and action and default to the specified default module/controller/action - but it doesn't.
    Or, as alternative, I would expect a big fat exception.
    Am I doing something completely wrong?
    I'm afraid that it might have this problems on other systems too and while I'm going to sell my script this could lead to many hours spent on supporting clients.

    My system:
    - Athlon X2 5600+, 4 GB, Windows XP
    - Apache 2.2.4
    - PHP 5.2.3
    - Zend Framework from stable SVN (http://framework.zend.com/svn/framework/trunk/library/)

    My dispatcher looks like this:
    Code PHP:
    ini_set('include_path', PATH_INCLUDES.PS.PATH_MODULES.PS.PATH_THIRDPARTY.PS.PATH_ZEND.PS.ini_get('include_path'));
     
    require_once(PATH_ZEND.'Loader.php');
    Zend_Loader::loadClass('Zend_Controller_Front');
    Zend_Loader::loadClass('Zend_Controller_Request_Http');
    Zend_Loader::loadClass('Zend_Controller_Router_Rewrite');
    Zend_Loader::loadClass('Zend_Controller_Router_Route_Regex');
     
    // Setup required routes
    $router     = new Zend_Controller_Router_Rewrite();
    $router->addRoute('setLanguage', new Zend_Controller_Router_Route_Regex(
          '(offers|order|account|mates|faq|management)(?:/([^/]*))?(?:/([^/]*))?(?:/(.*))?/setLanguage/([^/]*)(/.*)*',
          array(
                'controller' => 'default',
                'action'     => 'changeLanguage'
          )
    ));
    $router->addRoute('offers', new Zend_Controller_Router_Route_Regex(
          'offers/(?:/([^/]*))?(?:/([^/]*))?(?:/(.*))?/setLanguage/([^/]*)(/.*)*',
          array(
                'controller' => 'default',
                'action'     => 'changeLanguage'
          )
    ));
     
     
    $controller = Zend_Controller_Front::getInstance();
    $controller->throwExceptions(true);
    $controller->setParam('noErrorHandler', TRUE);
    $controller->setParam('noViewRenderer', TRUE);
    $controller->setParam('useModules', true);
    $controller->setBaseUrl(!is_null($urlPathPart) && strlen($urlPathPart) ? '/'.$urlPathPart : '');
    $controller->setRouter($router);
    $controller->setDefaultModule('default');
    $controller->setDefaultControllerName('default');
    $controller->setDefaultAction('default');
    $controller->setControllerDirectory(array(
          'account'    => PATH_MODULES.'account'.DS.'controllers'.DS,
          'default'    => PATH_MODULES.'default'.DS.'controllers'.DS,
          'faq'        => PATH_MODULES.'faq'.DS.'controllers'.DS,
          'management' => PATH_MODULES.'management'.DS.'controllers'.DS,
          'mates'      => PATH_MODULES.'mates'.DS.'controllers'.DS,
          'offers'     => PATH_MODULES.'offers'.DS.'controllers'.DS,
          'order'      => PATH_MODULES.'order'.DS.'controllers'.DS
    ));
    $controller->dispatch();
    Don't mind the constants - these are only paths and they all exist.

  2. #2
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You might want to be more specific about what exactly is happening. What does taskman say? What does filemon say? Access log? Rewrite log? etc

  3. #3
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Taskamanager says 50&#37; load, nothing in the logs except for "Error in my_thread_global_end(): 1 threads didn't exit"
    Tried hard to find the problem but since I need to get on I'll skip Zend for the moment and develop a simple "framework" for this project.

    -> no more help needed for the moment, thanks.

  4. #4
    ¬.¬ shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    It is a MySQL error not a PHP error.
    http://bugs.mysql.com/bug.php?id=25621

    So probably update MySQL to the latest version.
    Oh also update libmysql.dll that PHP uses.
    http://forums.mysql.com/read.php?10,...077#msg-153077
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.


  5. #5
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Don't think it's got to do with mysql - I haven't even established a mysql connection and I don't think Zend tries to do this without beeing explicitly told so
    Perhaps I'm giving it a try later on when there's more spare time for experiments.

  6. #6
    ¬.¬ shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    The whole thing is a PHP and MySQL problem even when no connection is made to MySQL it seems.

    http://bugs.php.net/bug.php?id=41350
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.


  7. #7
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hm...tested it, even with any extensions turned off - no change.
    Seems to be a problem with the ZF rewrite router - if I call
    Code php:
    $router = new Zend_Controller_Router_Rewrite();
    $router->removeDefaultRoutes();
    $frontController->setRouter($router);
    and don't add any routes afterwards I see the default module/controller/action.
    As soon as I add a simple rule like that:
    Code php:
    $router->addRoute('index', new Zend_Controller_Router_Route_Module(array(), $frontController->getDispatcher(), new Zend_Controller_Request_Http()));
    or if I remove the
    Code php:
    $router->removeDefaultRoutes();
    it again keeps loading and loading.

    No entries in apache error_log, none in PHPs, none in the rewrite log.
    Damned, I hate things like that.
    BTW, even an update to the latest 5.2.4 stable didn't have any effect.

  8. #8
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try setting RewriteLogLevel to the maximal value (9, IIRC)

  9. #9
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It was already 9.
    I don't think that it's got something to to with Apache itself, to me it seems that ZF is the problem.
    Everything works fine until I call $front->dispatch().
    Even my test controller (existing one, module "offers", controller "index") works fine.
    It just doesn't seem to work if there is no class file for the requested controller in the modules directory.

  10. #10
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK, managed to spend some spare time on the problem.
    I trial-and-error-debugged the dispatcher call since everything works fine until $front->dispatch().
    It seems idiotic - but it hangs on a simple if-statement with a single retrun true in it!

    Since I don't use an other dispatcher Zend uses Dispatcher_Standard and calls following functions.
    For simplicity I commented the parts.
    Code PHP:
    // taken from Zend's Standard-Dispatcher, removed DocBlocks for readability
            public function isDispatchable(Zend_Controller_Request_Abstract $request)
        {
            $className = $this->getControllerClass($request);
    // die('Test 4'); -> working
            if (!$className) {
    // die('Test 5'); -> working
                return true;
            }
     
            $fileSpec    = $this->classToFilename($className);
            $dispatchDir = $this->getDispatchDirectory();
            $test        = $dispatchDir . DIRECTORY_SEPARATOR . $fileSpec;
            return Zend_Loader::isReadable($test);
        }
     
        public function dispatch(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response)
        {
            $this->setResponse($response);
    // die('Test 1'); -> working
            /**
             * Get controller class
             */
            if (!$this->isDispatchable($request)) {
    // die('Test 2'); -> NOT working!
                if (!$this->getParam('useDefaultControllerAlways')) {
                    require_once 'Zend/Controller/Dispatcher/Exception.php';
                    throw new Zend_Controller_Dispatcher_Exception('Invalid controller specified (' . $request->getControllerName() . ')');
                }
     
                $className = $this->getDefaultControllerClass($request);
            } else {
    // die('Test 3'); -> NOT working!
                $className = $this->getControllerClass($request);
                if (!$className) {
                    $className = $this->getDefaultControllerClass($request);
                }
            }
    //...

    What I can't get:
    dispatch() calls isDispatchable().
    As I tested it, $className is FALSE and thus the if(!$className) { return true; } is executed (tested by die('Test 5'); )
    As soon as return true; is evaluated the script hangs and loads forever.

    *argh*....that's so stupid.
    I don't understand how this really, really simple part of the script can cause such problems.

    If I should provider more info on my environment (e.g. phpifno()) please feel free to ask.

  11. #11
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    *strike*
    After another deep dive into the Zend core I spotted the problem.
    It seems to be all about absolute paths on Windows.
    Well, is it that false to use absolute paths for files?
    I think not - I like to use absolute paths due to the fact that I can explicitly tell wich file to include and no include_path interferes.

    OK, to the point.
    If using absolute paths on Windows, especially for controller directories, do never ever use the drive letter.
    Zend's isReadable() that checks the existence of the requested controller (that doesn't exist in filesystem) checks it against all known include_paths.
    With a drive letter this would then read as X:/path/from/include_path/Y:/path/to/controller/that/cant/be/found/XYZController.php
    As soon as you remove the drive letter isReadable() correctly returns (bool)false - et voilą: the dispatcher redirects to the error module (or what ever you defined).

    I don't know if this is a bug in Zend's implementation - I tend to think it's a bug in PHP itself becaus Zend uses the native is_readable() function.
    Do you think I should file an issue in PHPs bugtracker?
    For ZF I'm going to file one as they should be aware of this problem - there are plenty more ZF-newbees like me that may run into this issue.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •