SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,053
    Mentioned
    66 Post(s)
    Tagged
    1 Thread(s)

    Opinions on Datastore class

    Submitted for comment is a datastoring class. As my framework has grown I've been looking for ways to speed it up. One is in how class and template discover is handled. This class assembles the collection of paths for the autoload function and for the framework's custom template loading function. Then if the caching system is turned on (set by a constant defined in the configuration of the site) it writes the cache file. Hence in a production environment this class isn't called at all.

    PHP Code:
    <?php
    /**
     * Datastore class. Creates the datastore - cache of class
     * and template paths and then writes the file to cache.
     */
    class PAMWF_Datastore {
        public function 
    __construct() {
            
    $this->setAllPaths();
            
            if (
    PAMWF_CACHE) {
                
    $this->cache();
            }
        }
        
        
    /**
         * Set All Path collections
         */
        
    protected function setAllPaths() {
            
    $this->setPaths('classPaths',
                
    PAMWF_ROOT.DIRECTORY_SEPARATOR.'classes'
                
    PAMWF_PROJECT.DIRECTORY_SEPARATOR.'classes' );

            
    $this->setPaths('templatePaths',
                
    PAMWF_ROOT.DIRECTORY_SEPARATOR.'templates'
                
    PAMWF_PROJECT.DIRECTORY_SEPARATOR.'templates' );        
        }
        
        
    /**
         * Setup the path collections. For now this is for
         * classes and template libraries.
         *
         * @param string $path
         */
        
    protected function setPaths$collection ) {    
            
    $ext = ($collection == 'templatePaths') ? 'phtml' 'php';
            
            foreach ( 
    func_get_args() as $path ) {
                
                if (
    $path == $collection) {
                    continue;
                }
                
                if (
    is_array($path)) {
                    
    $this->setPaths$collection$path );
                }
                else {
                    if (!
    is_dir($path)) {
                        throw new 
    PAMWF_FatalException('Invalid Path: ' $path );
                    }
                    
                    if ( 
    $files glob($path "/*.$ext")) {
                        foreach (
    $files as $file) {
                            if (
    is_dir($file)) {
                                continue;
                            }
                            
                            
    PAMWF::${$collection}[pathinfo($filePATHINFO_FILENAME)] = $file;
                        }
                    }    
                    
                    if ( 
    $paths glob($path "/*"GLOB_ONLYDIR) ) {
                        foreach (
    $paths as $dir) {
                            
    $this->setPaths$collection$dir );
                        }
                    }
                }
            }
        }
        
        
    /**
         * Cache the discovered collection of paths for later use.
         */
        
    protected function cache() {
            
    $output '<?php PAMWF::$classPaths = array ('."\n";
            
            foreach (
    PAMWF::$classPaths as $key => $value) {
                
    $output .= "'$key' => '$value',\n";
            }
            
            
    $output .= ");\n\n".'PAMWF::$templatePaths = array('."\n";

            foreach (
    PAMWF::$templatePaths as $key => $value) {
                
    $output .= "'$key' => '$value',\n";
            }

            
    $output .= '); ?>';
                
            
    file_put_contents(PAMWF_PROJECT.'/cache/datastore.php'$output);
        }
    }
    ?>
    Couple of notes. First, note that the root paths are examined before the project paths. Because of this if a programmer elects to they can override a class or (more likely) a template definition that is framework wide in favor of a custom one (For example, the 404 not found page's template). To override a class in this manner would be unusual since the recommended method is to extend an existing class rather than overwrite it entirely.

    I considered removing this overwriting feature from the class area entirely but left it in in the event it might be useful.

    I know the cache function can be refactored but other than that I'm out of ideas on how to tighten this beyond the fact that I can avoid it's use entirely in production via the cache it creates.

    For reference here are the autoload and template functions that make use of the output of this class -- note that they are in two different classes.

    PHP Code:
    <?php
    /* Taken from class PAMWF */
        
    public static function autoload$className ) {        
            if (
    array_key_exists($classNamePAMWF::$classPaths)) {
                require_once(
    PAMWF::$classPaths[$className]);
                return 
    true;
            }
            else {
                return 
    false;
            }
        }

    /* Taken from class PAMWF_Controller */
        
    protected function findTemplate($template) {
            if (
    array_key_exists($templatePAMWF::$templatePaths)) {
                return 
    PAMWF::$templatePaths[$template];
            }
            else {
                throw new 
    PAMWF_Exception('Unable to find template '.$template);
            }        
        }

    /* Example of a call to the findTemplate function */
    include( $this->findTemplate('myTemplate'));

    ?>
    Thoughts and comments welcome.

  2. #2
    SitePoint Addict Mastodont's Avatar
    Join Date
    Mar 2007
    Location
    Czech Republic
    Posts
    375
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    $output = '<?php PAMWF::$classPaths = array ('."\n";
    ....
    Serialize/unserialize way of array storing is IMHO simpler.

  3. #3
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,053
    Mentioned
    66 Post(s)
    Tagged
    1 Thread(s)
    Simpler? yes. Faster? no. As executable PHP code the datastore can be memcached after first eval. Speed is the first consideration in this particular code block.

  4. #4
    SitePoint Addict Mastodont's Avatar
    Join Date
    Mar 2007
    Location
    Czech Republic
    Posts
    375
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    According to manual are arrays stored in memcache in serialized form ...
    http://www.php.net/manual/en/function.memcache-add.php

  5. #5
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Well, in that case why not use a function made for this: Var_Export():
    PHP Code:
    <?php
        
    protected function cache() {
            
    File_Put_Contents(PAMWF_PROJECT.'/cache/datastore.php'SPrintF('<?php
    PAMWF::$classPaths = %s;
    PAMWF::$templatePaths = %s;
    ?>'
    Var_Export(PAMWF::$classPathstrue), Var_Export(PAMWF::$templatePathstrue)));
        }
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona


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
  •