ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Extending php Exception class... how to integrate into CI

December 14, 2007 8:39pm

Subscribe [7]
  • #1 / Dec 14, 2007 8:39pm

    ddesign

    4 posts

    Hi,

    I am new to CI and would like to write custom exceptions (extend the PHP Exception class). How do I integrate custom exceptions into CI? Do I need to load the library with $this->load->library(“Exception_document_invalid_id”) in both the class that throws it and the class that traps it? How do I throw and trap it when its loaded (named) like this? I tried a few things but nothing worked. Any help would be most appreciated. Hopefully this can be done. Below is an example of what I am trying to do:

    // the extended exception class (not the CI Exception class but the native PHP exception class)
    
    class Exception_document_invalid_id extends Exception  {
         public function __construct($id) {
            ....
            $code = 101;
            $message = "Invalid document ID='" . $id . "'.";
            parent::__construct($message, $code); 
        }
        ...
    }
    
    // the class throwing the custom exception
    
    class Document_model extends Model 
    {
        ....
        function get_document($id)
        { 
                 // test to see if document exists in DB, throw exception if not.
                 .....
                 throw new Exception_document_invalid_id($id);
        }
        ....
    }
    
    // the class trapping the exception
    
    class Document extends Controller {
         ....
        function view()
        {
                  try
                  { 
                        .....
                        $this->load->model('Document_model');
                        $document = $this->Document_model->get_document($id);
                        .....
                  } 
                 catch (Exception_document_invalid_id $ex)
                 {
                         $data['error_main'] = get_user_friendly_message($ex->getCode());
                         log_message('error', "Document:view " . $ex->getMessage(), false);
                 }
                 catch (Exception $ex)
                 {
                           $data['error_main'] = "Could not retrieve document. Unknown error.";
                           log_message('error', "Document:view " . $ex->getMessage(), false);
                 }
            }
           ....
    }


    Many thanks!
    -d

  • #2 / Dec 14, 2007 9:03pm

    Michael Wales

    2070 posts

    Name it MY_Exceptions.php, change your code a bit:

    class MY_Exceptions extends CI_Exceptions {

    Save it to /applications/libraries/

  • #3 / Dec 14, 2007 9:11pm

    ddesign

    4 posts

    Hi Michael,

    Thanks for the reply! I am trying to extend the native php exception class (http://us2.php.net/exceptions) to create custom exceptions. How do I do this by extending the CI_Exceptions? This class seems to be the class for logging and showing errors.

    Thanks!
    -d

  • #4 / Dec 14, 2007 10:31pm

    ddesign

    4 posts

    I figured it out…. to use custom PHP exceptions in CI, you use Hooks. I basically followed the instructions for using the Zend Framework in CI (http://www.4webby.com/freakauth/tutorials/using-zend-framework-components-in-code-igniter) for my custom exception classes and it worked! You need to use “require_once” on the classes that throw the custom exception.

    Thanks!
    -d

  • #5 / Dec 16, 2007 3:55am

    coolfactor

    354 posts

    Actually, Michael was trying to point you to the “CodeIgniter way” of doing this. If Hooks work for you, then great, but there’s also the ability to sub-class the core libraries.

  • #6 / Dec 16, 2007 10:15pm

    ddesign

    4 posts

    I understand sub-classing the core libraries and have done so for some of the classes… I guess I don’t understand how to sub-class CI_Exceptions to get what I want. Or maybe I don’t understand what you are saying. I prefer to use the same style of exception handling I use in .NET—creating custom exceptions (extending the language’s exception classes) and using try/catch to trap exceptions. As far as I can tell, I cannot extend the CI_Exceptions class and get a custom exception that I can trap. If this can be done, it would be great if you could provide an example.

    But maybe you mean I should extend the CI_Exceptions class by adding an array of exceptions and somehow handling the exceptions here and this would be in step with the CI way of handling exceptions (and backward compatible with PHP 4), i.e., 

    class MY_Exceptions extends CI_Exceptions {
    ....
       var $exceptions = array(
        E_CUSTOM_EXCEPTION_1    =>    'Custom message 1 here', 
        E_CUSTOM_EXCEPTION_2    =>    'Custom message 2 here',
        E_CUSTOM_EXCEPTION_3    =>    'Custom message 3 here',
            ....
       );
    ....
    }
  • #7 / Dec 16, 2007 11:13pm

    coolfactor

    354 posts

    You’re on the right track with that. You can do anything you want with your subclass.

    1. override methods defined in the parent class
    2. introduce new methods
    3. define new class variables
    4. define constants

    PHP 5 introduces the set_exception_handler() function that you could utilize. CodeIgniter aims to remain compatible with PHP 4, so it doesn’t use this feature, but you could in your subclass. PHP 4 has the set_error_handler() function that might also be useful.

  • #8 / Dec 16, 2007 11:59pm

    ddesign

    4 posts

    After reading a bit more on exception handling in PHP and looking at the CI code (specifically the set_error_handler callback function), I now understand what you are saying, especially the part about set_exception_handler(). Error handling in PHP is a little different from .NET and requires a different approach. I really appreciate all the help with this issue. This really clears things up.

  • #9 / Feb 25, 2008 11:40am

    AtlantixMedia

    81 posts

    I also need to extend the CI_Exceptions class.

    I named it MY_Exceptions.php and put it in /applications/libraries/

    <?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
    
    class MY_Exceptions extends CI_Exceptions{
        
        function MY_Exceptions(){
            parent::CI_Exceptions();
            
        }
    
        function show_404($page = '')
        {
        echo 'test';
        }
    
        function show_error($heading, $message, $template = 'error_general')
        {
    echo 'test';    
    }
    
        function show_php_error($severity, $message, $filepath, $line)
        {
             echo 'test';
             }
    }
    ?>

    however, functions in MY_Exceptions do not seem to be overridden at all. functions in Exceptions are the one which are run

  • #10 / Feb 17, 2010 4:35pm

  • #11 / Nov 10, 2011 7:57pm

    br4ssm0nk3y

    1 posts

    For anyone who likes throwing different Exception types (EG: NotFoundException), I decided to define my class extensions in

    core/MY_Exceptions.php

    <?php
    if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    
    class NotFoundException extends Exception {}
    class EtcException extends Exception {}
    
    class MY_Exceptions extends CI_Exceptions {
    }
  • #12 / Jun 07, 2012 12:16am

    Donald Hasson

    1 posts

    This is an old post, but in case this helps someone.

    When extending core classes you need to place your file in the application/core directory; not in the libraries folder. See http://ellislab.com/codeigniter/user-guide/general/core_classes.html. Your extended class will not get called otherwise.

    Also, I believe the below needs a constructor something closer to this:

    public function __construct()
        {
            parent::__construct();
        }

    Hopefully that helps.

    I also need to extend the CI_Exceptions class.

    I named it MY_Exceptions.php and put it in /applications/libraries/

    <?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
    
    class MY_Exceptions extends CI_Exceptions{
        
        function MY_Exceptions(){
            parent::CI_Exceptions();
            
        }
    ...


    however, functions in MY_Exceptions do not seem to be overridden at all. functions in Exceptions are the one which are run

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases