this is the base engine of my framework called conventionally mashup it is currently in alpha versions but is coming along nicely. so guys dont be nice grill this code for any mistakes or things that could be better.

bootstrap.php

<?php

/* directory seperator constant */
define('DS' , '/');

/* php extension constant */
define('EXT' , '.php');

/* mashup version contant */
define('MASHUP_VERSION' , '0.1');

/* supported php version by Mashup */
define('SUPPORTED_PHP' , '5.3.0');

/* defines the paths constants and application and system directory names */
function define_paths($app_dir_name = 'application' , $sys_dir_name = 'system')
{
    /* define __BASEPATH is the root path to the root directory*/
    if(!defined('__BASEPATH__'))
    {
        /* replace all \ slashes with linux style slash / */
        define('__BASEPATH__' , str_replace('\\' , '/' , getcwd()) . DS);
    }

/* the __SYSTEM__ path constant to the system directory */
if(!defined('__SYSTEM__'))
{
    define('__SYSTEM__' , __BASEPATH__ . $sys_dir_name . DS);
}

/* the __APP__ path constant to the application directory */
if(!defined('__APP__'))
{
    define('__APP__' , __BASEPATH__ . $app_dir_name . DS);
}

/* define the __BASE__ path to the base directory loacted inside the system directory */
if(!defined('__BASE__'))
{
    define('__BASE__' , __SYSTEM__ . 'base' . DS);
}

/* define the __CONFIG__ constant */
if(!defined('__CONFIG__'))
{
    define('__CONFIG__' , __APP__ . 'settings' . DS);
}
}

/* check if the path constants have been defined */
if(!defined('__BASEPATH__'))
{
    /* define the contants if not defined */;
    define_paths();
}

/* get the global functions */
require_once(__BASE__  . 'globals' . EXT);

/* valid version of php */
compare_php(SUPPORTED_PHP);


// ------ test case on loading exception class and throwing a exception that is logged to the logs file.
try{
    makeit();
}

catch(mashup_exception $e)
{
    $e->log('exception log test');
}

function makeit()
{
    if(!isset($thisstuff))
    {
        load('exception');
        throw new mashup_exception('its all messed up');
    }
}

globals.php

<?php if(!defined('__BASEPATH__')){exit('No Direct Access');}


/* compare PHP_VERSION against a version number */
function compare_php($supported_version)
{
    /* PHP_VERSION number less than version number */
    if(PHP_VERSION < $supported_version)
    {
        /* if comparison is less than exit and show message */
        exit('Your version of php :"' . PHP_VERSION . '" is not supported by Gasoline Framework');
    }

/* else return true */
return(TRUE);
}

/* ----------------------------------------------------------------------------------------------- */

/* a better version of is_writeable() */
/* if safe_mode or windows OS create a tmp file and attempt to write to it.*/
function is_file_writeable($file)
{
   /* check for safe mode */
   if (@ini_get("safe_mode") == FALSE AND is_writeable($file) === TRUE)
   {
      /* return true if writeable */
      return(TRUE);
   }

   /* check if dir */
   if (is_dir($file))
   {
      /* create a tmp file */
      $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));

  /* open file with read/write privales */
  if (!$fp = @fopen($file, 'rw'))
  {
     return(FALSE);
  }

  /* close and change file permissions */
  @fclose($fp);
  @chmod($file, 0600);
  @unlink($file);
  return(TRUE);

}

/* re attempt to open file */
elseif (!$fp = @fopen($file, 'rw') === FALSE)
{
   return(FALSE);
}
/* return true if all is ok */
fclose($fp);
return(TRUE);
}



/* ----------------------------------------------------------------------------------------------- */



function load($class , $dir = 'library' , $prefix = 'mash')
{
    static $__classes = array();
    if(isset($__classes[$class]))
    {
        return $__classes[$class];
    }

else
{
  foreach(array(__APP__ , __SYSTEM__) as $path)
  {
     $_prefix = $prefix;
     if(file_exists($path . $dir . DS . $class . EXT))
     {
         require($path . $dir . DS . $class . EXT);
         if(class_exists($class , FALSE))
         {
            is_loaded($class);
            $__classes[$class] = new $class();
            return $__classes[$class];
         }
     }


     if(file_exists($path . $dir . DS . $_prefix . $class . EXT))
     {
         require($path . $dir . DS . $_prefix . $class . EXT);
         if(class_exists($prefix.$class , FALSE))
         {
            is_loaded($_prefix.$class);
            $__classes[$_prefix.$class] = new $class();
            return $__classes[$_prefix.$class];
         }
     }
  }

 return(FALSE);
   }

  return(FALSE); 

}



/* ----------------------------------------------------------------------------------------------- */



function is_loaded($class)
{
    static $__loaded = array();
    if(isset($__loaded[$class]))
    {
        return $__loaded;
    }

else
{
    $__loaded[$class] = $class;
}

return $__loaded;
}

function get_config(array $replace = array())
{
    if(file_exists(__CONFIG__ . 'settings' . EXT))
    {
        require(__CONFIG__ . 'settings' . EXT);
        if(!isset($settings) && !is_array($settings))
        {
            exit('your config file does not seem to be formatted correctly');
        }

    if(count($replace) > 0)
    {
        foreach($replace as $k => $v)
        {
            if(isset($settings[$k]))
            {
                $settings[$k] = $v;
            }
        }
    }
}

else
{
    return(FALSE);
}

return $settings;
}



/* ----------------------------------------------------------------------------------------------- */



function get_item($item)
{
    $config = get_config();
    if(isset($config[$item]))
    {
        return $config[$item];
    }

return(FALSE);
}

function exception_handler()
{

}


?>

library class exception.php

class mashup_exception extends Exception
{
    public function log($message , $level = 'ERROR' , $__php_error = 0)
    {
        $_LE = load('log');
        $_LE->write_log($message , $level , $__php_errror);
    }
} 

library class logs.phjp

<?php if(!defined('__BASEPATH__')){exit('No Direct Access');}

define('__LOGS__' , __SYSTEM__ . 'logs' . DS);

class log 
{
    private $log_levels = array( 1 =>'ERROR' ,  2 => 'DEBUG' ,3 => 'RESULT' , 4 => 'ALL');

private $log_enabled = FALSE;

private $log_date;

private $log_paths;

private $log_ready = FALSE;

public function __construct()
{
    $this->log_enabled = get_item('log_enabled');
    $this->log_date =  get_item('date_format');
    $this->log_path = get_item('log_path');

    if($this->log_enabled === FALSE)
    {
        exit('Logging Is Not Currently Enabled');
    }

    if($this->log_ready === TRUE)
    {
        return;
    }

    elseif($this->log_path === null or empty($this->log_path))
    {
        $this->log_path = __LOGS__;
        if(file_exists($this->log_path) && is_file_writeable($this->log_path) === TRUE)
        {
           $this->log_ready = TRUE;
        }
    }

    elseif(!empty($this->log_path) && file_exists($this->log_path))
    {
            $this->log_ready = TRUE;
    }

    return(FALSE);
}



public function write_log($_message , $level = 0 , $_php_error = 0)
{
    if($this->log_ready === FALSE)
    {
        exit('Logging Could Not Be Configured Correctly And Currently Is Not In Ready State');
    }

    if($this->log_ready === TRUE)
    {
        if(in_array($level , $this->log_levels))
        {
            $filepath = $this->log_path .'log - '.date('y-m-d') . EXT;
            $mess = 'Logged : ['. date($this->log_date) .']  Level:['.$level.'] PHP Error:['. $_php_error .'] Message: '.$_message ."\n";
        }

        if(! $fp = @fopen($filepath , 'ab'))
        {
           return(FALSE);
        }

        @flock($fp , LOCK_EX);
        @fwrite($fp , $mess);
        @flock($fp , LOCK_UN);
        @fclose($fp);
        @chmod($this->log_paths , 0600);
        return(TRUE);
    }

    return(FALSE);
}
}

    A couple of things on quick view.

    Why are you using the @ ? I don't see any need to use it and if anything will hinder any debugging if you run into serious errors such as the script terminating.

    Why is your library class.logs.php file accessible via a simple http request ? It should live outside the document root.

    Whats the purpose of the load function in globals ? Why not integrate your load function with PHPs [man]autoload[/man] this way when you want a class you do not need to load it within your code as PHP will do that for you.

    Another thing your get_config can be changed to use array_merge rather than looping through the replace array e.g.

    function get_config(array $replace = array())
    {
        if(file_exists(__CONFIG__ . 'settings' . EXT))
        {
            require(__CONFIG__ . 'settings' . EXT);
            if(!isset($settings) && !is_array($settings))
            {
                exit('your config file does not seem to be formatted correctly');
            }
    
        $settings = array_merge( $settings, $replace );
    }
    
    else
    {
        return(FALSE);
    }
    
    return $settings;
    } 
    

      for your first question the reason why i use and many other projects use this technique is it is much easier to just supress the error handling on certain important things than write a whole conditional to handle the error rather than letting php output the problem.

      to answer your question on the logs class is it only has 1 purpose and that is to log errors and other info and directly accessing the log class is not possible without atleast attempting to go through the base engine to access the logs class directly if you know how let me know? . now the logs them self are stored outside of the root and file has a filelock on and permissions changed to read only no need to read the logs from my logs class as that is to big of a risk.

      now a question i was hoping someone would ask this took this took along time and alot of hours of thinking why not just use a autoloader and autoload everything. well there comes 2 problems with autoloading and frameworks , first the handling unkown directory's that could possibly be needed? i thought i it had an easy solution of just extending the autoload class i would build but making someone or me re-write an autoload method for every directory is very boring and i dont want to do it all the time for every project. the simple solution was make a load function that could handle a wildcard directory.

      but an autoload class will be used for back up and at user choice.

      but there is still hope for the autoload class i have one in the works that maybe usefull that has multiple autoloaders registered so each section could be extended without having to re-write every path.

      and i don't know why i didn't use array merge just didn't think of it i guess been useing C alot so use to having to write everything out.

      but thanks for the critique and corrections i will take a look at every thing you mentioned and test it all up see if it handles correctly.

        jgetner;10977686 wrote:

        now a question i was hoping someone would ask this took this took along time and alot of hours of thinking why not just use a autoloader and autoload everything. well there comes 2 problems with autoloading and frameworks , first the handling unkown directory's that could possibly be needed? i thought i it had an easy solution of just extending the autoload class i would build but making someone or me re-write an autoload method for every directory is very boring and i dont want to do it all the time for every project. the simple solution was make a load function that could handle a wildcard directory.

        but an autoload class will be used for back up and at user choice.

        but there is still hope for the autoload class i have one in the works that maybe usefull that has multiple autoloaders registered so each section could be extended without having to re-write every path.

        Not sure why you need an autoload for each directory that doesn't make sense. For example the Zend Framework uses the class name to determine which folder and file name to use e.g.

        Application_Model_Class

        Would be found in application/model/Class.php

        for your first question the reason why i use and many other projects use this technique is it is much easier to just supress the error handling on certain important things than write a whole conditional to handle the error rather than letting php output the problem.

        Ive personally never understood this lazy approach to programming, to me its the equavlient of a car not showing you the correct temperature until its too late and the smoke comes bellowing out from the bonet.

        Another quick inspection of your code too in globals.php

        /* check if dir */
           if (is_dir($file))
           {
              /* create a tmp file */
              $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));
        
          /* open file with read/write privales */
          if (!$fp = @fopen($file, 'rw'))
          {
             return(FALSE);
          }
        
          /* close and change file permissions */
          @fclose($fp);
          @chmod($file, 0600);
          @unlink($file);
          return(TRUE);
        
        } 
        

        I don't think you really understand what the fopen mode options mean. What you are doing is opening your file for reading and writing but not necessarily giving the file these permissions. The fact that you aren't actually writing or reading the file means you can probably just want use [man]touch[/man], but even that doesn't make sense as you then delete this file. If its a directory why not just check if the directory is writable using the [man]is_writable[/man] function it should be enough to determine whether you can write to the directory or not.

          Not sure why you need an autoload for each directory that doesn't make sense. For example the Zend Framework uses the class name to determine which folder and file name to use e.g.

          Application_Model_Class

          Would be found in application/model/Class.php

          not for each directory but each framework component system, library , application that can be easily extended so lets say you create a new directory for your admin and you want some classes to be autoloaded just extend the application autoloader to include that directory.

          and i do not like the zend approach as that is why php created namespaces and i like to keep thing a little more rapped no 155 character class names...

          but i will be adding in namespaces to support a better design.

          Ive personally never understood this lazy approach to programming, to me its the equavlient of a car not showing you the correct temperature until its too late and the smoke comes bellowing out from the bonet.

          code supressed errors

               @fclose($fp);
               @chmod($file, 0600);
               @unlink($file); 
          

          code with conditionals and errors and the reasons why we use error suppression where it fits best.

          	 if(fclose($fp) === FALSE)
          	 {
          	    // hackers we have a file open lets show you the error to comfirm
          		/* now we must log the errors witch would involve alot more calls and conditions to prevent
          		 possible hacks so in the end you will write alot more to be just as secure as not showing anything. */
          	 	exit('Must Exit As Now A File Is Left Open Cannot Continue');
          	 } 
          
           if(chmod($file , 0600) === FALSE)
           {
              // hell if we cannot open the file maube the hackers can by letting them know.
           	trigger_error('File Could Perrmissions Could Not Be Changed');
           }
          
           if(unlink($file) === FALSE)
           {
           	// well this is just pointless if you cannot delete the file you really wanna tell them?.
          	throw new Exception('We Cannot Delete File Why Becuase File Is For Some Crazy Reason UnDeleteable?');
           }
          

          I don't think you really understand what the fopen mode options mean. What you are doing is opening your file for reading and writing but not necessarily giving the file these permissions. The fact that you aren't actually writing or reading the file means you can probably just want use touch, but even that doesn't make sense as you then delete this file. If its a directory why not just check if the directory is writable using the is_writable function it should be enough to determine whether you can write to the directory or not.

          well this actually takes into count to check if a directory is writeable and not just files to check if a directory is writeable with safe_mode on and on windows you must actually write a tmp file and check if you can open it with r - w permissions then close that file change the permissions and delete it .

          else i basically just check the file

            Write a Reply...