Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Ongelma Zend Frameworkin ErrorControllerin kanssa

Damiqib [06.04.2008 23:49:32]

#

Olen aloittelemassa Zend Frameworkin käyttöä ja muuten olen kaiken saanut toimimaan haluamallani tavalla, mutta virheidenhallinta ei toimi (toimi hetken, mutta vaikka nyt teen kaiken esimerkin mukaan nollasta uusiksi, ei virheidenhallinta toimi).

Ongelmana on, että framework ei ohjaa löytymättömiä controllereita ja actioneja ErrorControllerille, vaan näyttää aina vain php-errorin, vaikka oletuksenahan virheelliset urlit pitäisi ohjautua ko. controllerille ja tuloksen tapahtua sen mukaisesti.

Esim: http://localhost/zend -> tulostaa ihan oikein IndexControllerin mukaisesti
Esim: http://localhost/controller -> valittaa: 'Invalid controller specified (controller)', vaikka pitäisi valittaa: 'Invalid controller specified (error)' (jos controlleria ei ole luotu) tai renderöidä ErrorControllerin mukaisesti (jos controller löytyy).

Riippumatta siitä, miten koodia muutan, en saa koskaan tätä:

Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (error)'...

...vaan aina valituksen, että haettua controlleria tai actionia ei löytynyt.

Rakenne:

/application
  /controllers
    IndexController.php
    ErrorController.php
  /models
  /views
    /scripts
      /index
        index.phtml
      /error
        error.phtml
/public
  .htaccess
  index.php

IndexController.php

<?php

  class IndexController extends Zend_Controller_Action
  {
    function indexAction()
    {

    }
  }

?>

ErrorController.php

<?php

  class ErrorController extends Zend_Controller_Action
  {
    public function errorAction()
    {

    }
  }

?>

.htaccess

RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

index.php

<?php

  error_reporting(E_ALL|E_STRICT);
  ini_set('display_errors', 'on');

  ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . '../../__library');

  require_once 'Zend/Loader.php';
  Zend_Loader::loadClass('Zend_Controller_Front');

  $front = Zend_Controller_Front::getInstance();
  $front->setControllerDirectory('../application/controllers');

  /**
   * Tälläkään ei ole mitään vaikutusta (eikä pitäisikään olla, koska asetuksen pitäisi olla oletuksena 'false')
   */
  $front->throwExceptions(false);

  $front->dispatch();

?>

Wizard [07.04.2008 08:57:11]

#

Ensinnäkin tuo ErrorController pitää rekisteröidä plugariksi:

<?php
$front->registerPlugin(new OmaErrorController());
?>

Tuo, että jos ei löydy controlleria, niin se on huolestuttavaa. Silloin kannattaisi ehkää ajaa ZF:ää modulerakenteella ja ohjata virhetilanteessa etusivulle kaikki liikenne. Controllerin tai modulin löytymättömyys on aina aika iso virhe, actionin puuttuminen voidaan helposti vielä korjata.

Controllerin tai modulin puuttumattomuus pystytään kuitenkin tunnistamaan, mutta sinun pitää tunnistaa kyseinen ongelma ENNEN kuin dispatcher ajetaan. Siihen on olemassa ZF:ssä oma järjestelmä johon löydät vastauksen linkistä http://framework.zend.com/manual/en/zend.controller.html

Controllereiden sisällä voit tehdä magic metodin:

<?php
public function __call($method, $args) {
	// Forward to indexAction
	$this->_forward('index');
	}
?>

ErrorController käyttää syntaksia jotakuinkin hieman transaktio tyyliin alla olevan mallin mukaan.

Tässä ihan manuaalin mukaan mitä tarvitset (tämä EI OLE suora ratkaisu koodiisi, sinun pitää rakentaa se tämän mallin mukaisesti ITSE):

<?php
/**
 * Define a custom exception class
 */
class MyException extends Exception
{
    // Redefine the exception so message isn't optional
    public function __construct($message, $code = 0) {
        // some code

        // make sure everything is assigned properly
        parent::__construct($message, $code);
    }

    // custom string representation of object
    public function __toString() {
        return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
    }

    public function customFunction() {
        echo "A Custom function for this type of exception\n";
    }
}


/**
 * Create a class to test the exception
 */
class TestException
{
    public $var;

    const THROW_NONE    = 0;
    const THROW_CUSTOM  = 1;
    const THROW_DEFAULT = 2;

    function __construct($avalue = self::THROW_NONE) {

        switch ($avalue) {
            case self::THROW_CUSTOM:
                // throw custom exception
                throw new MyException('1 is an invalid parameter', 5);
                break;

            case self::THROW_DEFAULT:
                // throw default one.
                throw new Exception('2 isnt allowed as a parameter', 6);
                break;

            default:
                // No exception, object will be created.
                $this->var = $avalue;
                break;
        }
    }
}


// Example 1
try {
    $o = new TestException(TestException::THROW_CUSTOM);
} catch (MyException $e) {      // Will be caught
    echo "Caught my exception\n", $e;
    $e->customFunction();
} catch (Exception $e) {        // Skipped
    echo "Caught Default Exception\n", $e;
}

// Continue execution
var_dump($o);
echo "\n\n";


// Example 2
try {
    $o = new TestException(TestException::THROW_DEFAULT);
} catch (MyException $e) {      // Doesn't match this type
    echo "Caught my exception\n", $e;
    $e->customFunction();
} catch (Exception $e) {        // Will be caught
    echo "Caught Default Exception\n", $e;
}

// Continue execution
var_dump($o);
echo "\n\n";


// Example 3
try {
    $o = new TestException(TestException::THROW_CUSTOM);
} catch (Exception $e) {        // Will be caught
    echo "Default Exception caught\n", $e;
}

// Continue execution
var_dump($o);
echo "\n\n";


// Example 4
try {
    $o = new TestException();
} catch (Exception $e) {        // Skipped, no exception
    echo "Default Exception caught\n", $e;
}

// Continue execution
var_dump($o);
echo "\n\n";
?>

Tässä on linkki siihen mitä sinun pitää opetella käyttämään: https://www.php.net/exceptions TAI sitten ZF:n oma malli http://framework.zend.com/manual/en/zend.exception.html


Vastaus kysymykseesi on kuitenkin:

<?php
try {
	// Ensin siis yritetään jotain
} catch (Exception $e) {
	// Heitetään ErrorControllerille jos ei TRY onnistu ja jos ErrorController tunnistaa ongelman
}

?>

EDIT: koska olen hyvällä tuulella, niin tässä on sinulle malliratkaisu:

<?php
		$errors = $this->_getParam('error_handler');

        switch ($errors->type) {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
                // 404 error -- controller or action not found
                $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');

                // ... get some output to display...
                break;
            default:
                // application error; display error page, but don't change
                // status code

                // ...

                // Log the exception:
                $exception = $errors->exception;
                $log = new Zend_Log(new Zend_Log_Writer_Stream('/tmp/applicationException.log'));
                $log->debug($exception->getMessage() . "\n" .  $exception->getTraceAsString());
                break;
        }
?>

Lisää tuo omaan ErrorControlleriisi ja tee antamieni ohjeiden mukaan. Toimii ainakin minulla todella hyvin.

Damiqib [07.04.2008 10:12:12]

#

Hieman tarkennusta:

Yritän siis käyttää ihan tuota Zend Frameworkin omaa virheidenhallintaa, jonka pitäisi Zendin mukaan olla oletuksena päällä ilman kikkailuja:
"By default, the error handler plugin is registered. This plugin expects that a controller exists to handle errors. By default, it assumes an ErrorController in the default module with an errorAction method."

...ja oma kokeiluni on tehty täysin tämän sivun videoiden mukaisesti: http://framework.zend.com/manual/videos­#bootstrappin
...ja kuten videoista huomaa, on oma esimerkkini sen mukainen ja pitäisi toimia oikein, mutta kuitenkaan virheelliset urlit eivät ohjaudu oikein error-controllerille...

Frameworkkina: Zend Framework 1.5.1 (kokeiltu asentaa uusiksi)

Wizard [07.04.2008 10:31:48]

#

Muistaakseni tuossa oletus controllerissa EI ole käsittelyä puuttuville controllereille ja moduleille. Actionit ovat hieman sellaisia, että niihin voi käyttää controllerin sisällä joko magic metodia __call tai sitten ne voidaan ajaa suoraan tuonne globaalille error controlerille.

ZF 1.5.x sarja on muuttanut (taas kerran) noita käsittelyitä hieman, mutta ainakin omissa järjestelmissä tuo virheidenkäsittely toimii tuolla viimeisellä edellisen viestin mallilla tosi hyvin. Muuta vain tuota outputtia '404 not found' kohtaa omaksesi. Tuo malli pitää olla sinun OMASSA error controllerissa sitten. ja kuten itsekin lainasit: "This plugin expects that a controller exists to handle errors".

Nähtävästi sinulla on sitten ongelmia itse ZF:n alustuksessa. En noita malleja nyt ole jaksanut plarata läpi kun ZF:n manuaalit ja mallit ovat aina ajastaan jäljessä nykyiseen uusimpaan versioon nähden. Esim. manuaaleissa on malleja jotka on tarkoitettu < 1.0.x versioihin ja ne eivät toimi nykyisissä versioissa millään.

-W-

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta