SitePoint Sponsor

User Tag List

Results 1 to 13 of 13
  1. #1
    SitePoint Enthusiast
    Join Date
    Mar 2005
    Posts
    53
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Application Message System?

    Hello everyone,

    I've been coding an app for awhile, and I have begun to feel the need for a centralized error message reposistory of one sort or another. While a database seems like the most logical choice for the data, I don't want to have to query a database each time I need to get an appropriate error message.

    How have any of you solved storing error messages? Any tips appreciated,

    Edit: I suppose this post dives into how to store small messages of any sort on a large scale. This might just be notification messages, status messages, etc. Also tips of having these things i18n enabled would be a plus .

    Regards,
    Last edited by illusina; Jun 1, 2005 at 18:03.

  2. #2
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'd be interested in hearing about people error handling frameworks. This is one big missing piece in PHP. PEAR botched error handling badly and the new Error Stack is not much better. I seems like you need a framework that can deal with both exceptions and non-exception error handling, both to support PHP4 and because you don't always want to use exceptions, but would like errors all handled in within one framework.
    Christopher

  3. #3
    SitePoint Guru
    Join Date
    Oct 2001
    Posts
    656
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A while ago I did what you might call a case study trying to design a framework with internationalization support. If I had found a good way to externalize messages (not just errors, but also stuff like form field labels), it would not be that hard to support multiple languages I thought.

    But it turned out to be quite ugly though, so I just stuck to the good'ol way of hardcoding them in English.

    In principle it is not that hard to externalize error messages though. Something like a Messages class with a static getMessage($messageID) method that opens some ini file and reads the message should be simple enough. You could divide the messages into separate files, one for each module perhaps, and add a $module parameter to the getMessage() method.

  4. #4
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here this might be of some use. It is not my code, it's been posted by someone in one of the threads I started about Internationalization. I use it now though, since it's cool.

    PHP Code:
    <?php
    class Translator{
        
        protected 
    $datasources;
        protected 
    $messages = array();
        protected 
    $lang 'EN';
        static protected 
    $INSTANCE;
        
        private function 
    __construct(){}
        
        function 
    addDatasource($datasource){
            
    $this->datasources[] = $datasource;
            
    $this->loadMessagesFromDatasource($datasource);
        }
        
        function 
    updateDictionary(){
            foreach(
    $this->datasources as $ds){
                
    $this->loadMessagesFromDatasource($ds);
            }
        }
        function 
    loadMessagesFromDatasource($ds){
            
    $this->messages =& array_merge($this->messages,$ds->loadMessages($this->lang));    
        }
        
        function 
    setLang($lang){
            !empty(
    $lang) && $this->lang $lang;
            if (!empty(
    $this->datasources))
                
    $this->updateDictionary();
        }
        
        function 
    getMsg($msg_id){
            if (
    func_num_args() > 1){
                
    $args func_get_args();
                unset(
    $args[0]);
                   return 
    vsprintf($this->messages[$msg_id], $args);
            }
            return 
    $this->messages[$msg_id];
        }    
        function 
    getInstance(){
             if (
    self::$INSTANCE == nullself::$INSTANCE = new Translator();
             return 
    self::$INSTANCE;
        }
        
        
    }

    abstract class 
    TranslatorDatasource{    
            
    //must return an array
            //Format:Array('msg_id'=>'msg','msg_id2'=>'msg2')
        
    abstract function &loadMessages($lang);
    }

    class 
    TranslatorDatasourceArray extends TranslatorDatasource{
        
        protected 
    $msgarray null;
        
        function 
    __construct(&$messageArray){
            
    $this->msgarray = &$messageArray;
        }
        function &
    loadMessages($lang){
            return 
    $this->msgarray[$lang];
        }
    }

    class 
    TranslatorDatasourceDB extends TranslatorDatasource{
        
        protected 
    $dictName;
        
        function 
    setDictionary($dict){
            
    $this->dictName $dict;
        }
        
        function &
    loadMessages($lang){
            
    $rs DAO_Factory::getDAO('Messages')->selectBy_Lang_AND_Dictionary($lang,$this->dictName);
            
    $msgs  =array();
            foreach(
    $rs as $row){
                
    $msgs[$row['msg_id']] = $row['msg'];
            }
            return 
    $msgs;
        }
        
    }

    class 
    DAO_Messages extends DAO_Base{
        
        function 
    selectBy_Lang_AND_Dictionary($lang,$dictName=false){
            
    $SQL "SELECT msg_id, msg FROM messages WHERE lang = '$lang'";
            
    $dictName && $SQL .=" AND dictionary = '$dictName'";
            return 
    $this->da->execute($SQL);
        }
    }

    ?>

  5. #5
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's rather hefty, Tim. If you have an app with many single words and messages, that is going to eat up clockcycles. It may not be nice and objectoriented, but this is something, I would rather solve with a hashmap and a global function. You can go with gettext or simply make your own. (The latter is presumably faster)

  6. #6
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Notice the various TranslatorDataSource(s). There is a TranslatorDataSourceArray, which would simply act like a HashMap.

    Or maybe I did not fully understand what you said?

  7. #7
    SitePoint Enthusiast
    Join Date
    Jun 2003
    Location
    Ljubljana, Slovenia
    Posts
    83
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    the Idea also crossed my mind .. since I have the privilege of working on big PHP applications .. really huge (dont ask)..

    the idea of framework I build in PHP was to handle pretty much everything ...
    User authentication
    Parameters handling (get post session ...)
    Site handler ( since we had to connect 3 sites in one big "thing" aka working project)
    Error handling
    Log handling ..
    etc ..

    and the error handling was really a bugger .. since I knew every part of the code can bring up an error of any kind .. not to mention the Localisation of errors for different languages .. this was fun !!

    ok .. localisation was pretty simple .. table of locales in DB and a class that reads them out in desired language .. easy

    errors werent so easy ...

    I created an Messenger class with static functions
    void addMessage($messageCode,$messageType);
    String getMessages($messageType);
    and whereever I needed to print out errors I just called the getMessages($mesageType); function ..
    $messageType is not just for Errors its for everything I wanted to put out in the sistem ..

    I build a stack of messages that were caught during execution so I could easily follow the things that got wrong or did affect one another .. in jboss I know one could use its loging system .. but since here is not available .. I picked this way .. I'm not sure if its the best one .. I'm not even sure if its the good one .. but it works for me .. and thats pretty much what I needed in the end

    to handle every possible message i need to know about in the sistem

    bye

    Armando
    PS: better ideas would be appreciated !!

  8. #8
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What does the PHP Manual say about creating custom Error handling ?

  9. #9
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DarkAngelBGE
    Notice the various TranslatorDataSource(s). There is a TranslatorDataSourceArray, which would simply act like a HashMap.
    Ok, I just skimmed past that and saw the db-code at the bottom. You'd probably want to change the Translator a bit - I see no easy way to make a TranslatorDatasourceGetText (see gettext)

  10. #10
    SitePoint Enthusiast
    Join Date
    Mar 2005
    Posts
    53
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hello,

    Thanks everyone for their thoughts and efforts -- this does indeed seem to be a troubling problem for us all; that is, there is no truly simply and elegant solution. I'm so far considering a few different approaches, the most promising of which is a modification of DarkAngelBGE's Translator approach. This particular approach has many advantages I can see so far, most important of which is data source androgony (once you write a driver for a given source, that is).

    A few design questions: Does it make sense to ever load in every language, as is done in DatasourceArray? Does it seem better to LazyLoad the objects?

    Thoughts appreciated,

  11. #11
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    DarkAngelBGE, perhaps you could add your Translator class code to the AP3 SourceForge Project. Then others, such as illusina or kyberfabrikken, could post their modifiications to show their ideas. Maybe start an "i18n" module there. I think if you could remove the dependency on your DAO_Base class it would be a very nice, usable set of classes.

    I'd be interested to see armandoxxx Messenger classes as well.

    All this good code and I hate to see it lost buried in some post.
    Christopher

  12. #12
    SitePoint Enthusiast
    Join Date
    Jul 2004
    Location
    Finland
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hello,

    It's nice to see that people like my Translator class

  13. #13
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    if you really like it, consider using static.


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
  •