Static Class inside library folder

#1
[eluser]Nicholas Hanks[/eluser]
I tried to create static class with all static methods inside library folder however I was not able to do that because by default Codeigniter tries to instantiate the class inside the library folder which my class design does not allow. My code is like this.
Code:
<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
class Data
{
    private static $_reader;
    private static $_instance = null;
    private static $_articles = null;

    private function  __construct()
    {
        $path = substr(BASEPATH, 0, -8).'\xmls\data.xml';
        try
        {
            self::$_reader = simplexml_load_file($path);            
        }
        catch (Exception $e)
        {
            echo $e->getMessage();
        }
    }

    public static function get_article($id)
    {
        self::_getInstance();
        $articles = self::get_articles();
        $result = array();

        foreach($articles as $article)
        {
            if($article['id'] == $id)
            {
                $result['id'] = $article['id'];
                $result['title'] = $article['title'];
                $result['heading'] =  $article['heading'];
                $result['content'] = $article['content'];
                break;
            }
        }
        return $result;
    }

    public static function article_exist($id)
    {
        $result = false;
        $id = trim($id);

        if(preg_match( '/^[0-9]+$/', $id))
        {
            $articles = self::get_articles();

            foreach($articles as $article)
            {
                if($article['id'] == $id)
                {
                    $result = true;
                    break;
                }
            }
        }
        return $result;
    }

    public static function get_articles()
    {
        self::_getInstance();
        if(!is_array(self::$_articles))
        {
            self::$_articles = array();
            foreach(self::$_reader->article as $article)
            {
                self::$_articles[] = array
                (
                    'id' => (int)$article['id'],
                    'title' => (string)$article->title,
                    'heading' =>  (string)$article->heading,
                    'content' => (string)$article->content
                );
            }
        }
        return self::$_articles;
    }

    private static function _getInstance()
    {
        if(!isset( self::$instance ))
        {
            $class = __CLASS__;
            self::$_instance = new $class();
        }
        return self::$_instance;
    }

}
/*
* End of class Data
* End of file helper/data_helper.php
*/
Now currently if I put this file inside helper folder then it works but logically speaking this class does not belongs inside helper folder. In controller I would like to call this class in this way.
Code:
if(Data::article_exist($id))
{
   $data['article'] = Data::get_article($id);
}
What is the proper way to do this kind of stuff in CI.

#2
[eluser]Jelmer[/eluser]
CI has no native way for loading static classes (or interfaces/abstracts). There's a couple of ways to go about it:
- Load as a helper, which is the only way to load without instantiating (as you mentioned)
- Load with another class by putting it in the same file (quite ugly)
- Use inlcude()
- Use an autoloader

I went with the last option, which I described here.

#3
[eluser]danmontgomery[/eluser]
I'm not aware of a 'proper' singleton implementation, I use __autoload so that I don't have to use CI's loader.

edit: too slow Wink

#4
[eluser]Nicholas Hanks[/eluser]
Thank you very much for the responses. I have found that if you use Modular Seperation you can circumvent this problem. Only thing is that you have to change this
Code:
$autoload['libraries'] = array('data');
to
Code:
$autoload['libraries'] = array();

#5
[eluser]Jelmer[/eluser]
So you unknowingly went with our suggestion to use an autoloader Wink (modular seperation comes with an autoloader for the libraries directory)

It's set using the spl_autoload_register function at line 4 of MY_Router.php:
Code:
spl_autoload_register('Modules::autoload');

And you can find the autoloader function at lines 139-148
Code:
/** Library base class autoload **/
public static function autoload($class) {
    
    /* don't autoload CI_ or MY_ prefixed classes */
    if (strstr($class, 'CI_') OR strstr($class, 'MY_')) return;
        
    if(is_file($location = APPPATH.'libraries/'.$class.EXT)) {
        include_once $location;
    }        
}

#6
[eluser]Nicholas Hanks[/eluser]
Yes you are right. Thank you very much for your feedback.


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2019 MyBB Group.