5
\$\begingroup\$

So I have started a PHP framework called ExCx and I haven't really had much experience in the professional development business.

I was just wondering if my structure/layout/methods are up to scratch?

EDIT: Forget the URL, added that. Normally I remember to omit the closing php tag...

In tandem with this I am building a PHP Blocks type thing, It's still early days for both projects.

<?php

    /****
    *
    *   ecCore Provides low-level debugging, error and exception functionality
    *   Matthew Day (CFHC Web Development 2011)
    *    @package: ExCx
    *   @version: 1.0
    *
    ****/

  class ecCore
  {

    //The following constants allow for pretty call backs to static methods
    const backtrace                                 = 'ecCore::backtrace';
    const call                                      = 'ecCore::call';
    const callback                                  = 'ecCore::callback';
    const checkOS                                   = 'ecCore::checkOS';
    const checkVersion                              = 'ecCore::checkVersion';
    const configureSMTP                             = 'ecCore::configureSMTP';
    const debug                                     = 'ecCore::debug';
    const detectOpcodeCache                         = 'ecCore::detectOpcodeCache';
    const disableContext                            = 'ecCore::disableContext';
    const dump                                      = 'ecCore::dump';
    const enableDebugging                           = 'ecCore::enableDebugging';
    const enableDynamicConstants                    = 'ecCore::enableDynamicConstants';
    const enableErrorHandling                       = 'ecCore::enableErrorHandling';
    const enableExceptionHandling                   = 'ecCore::enableExceptionHandling';
    const expose                                    = 'ecCore::expose';
    const getDebug                                  = 'ecCore::getDebug';
    const handleError                               = 'ecCore::handleError';
    const handleException                           = 'ecCore::handleException';
    const registerDebugCallback                     = 'ecCore::registerDebugCallback';
    const reset                                     = 'ecCore::reset';
    const sendMessagesOnShutdown                    = 'ecCore::sendMessagesOnShutdown';
    const startErrorCapture                         = 'ecCore::startErrorCapture';
    const stopErrorCapture                          = 'ecCore::stopErrorCapture';

    static private $captured_error_level = 0;
    static private $captured_error_regex = array();
    static private $captured_error_types = array();
    static private $captured_errors = array();
    static private $captured_errors_previous_handler = array();
    static private $context_shown = FALSE;
    static private $debug = NULL;
    static private $debug_callback = NULL;
    static private $dynamic_constants = FALSE;
    static private $error_destination = 'html';
    static private $error_message_queue = array();
    static private $exception_destination = 'html';
    static private $exception_handler_callback = NULL;
    static private $exception_handler_parameters = array();
    static private $exception_message = NULL;
    static private $handles_errors = FALSE;
    static private $handles_exceptions = FALSE;
    static private $show_context = TRUE
    static private $smtp_connection = NULL;
    static private $smtp_from_email = NULL;

    //Creates a nicely formatted backtrace to where the method is initally called
    static public function backtrace($remove_lines=0, $backtrace=NULL)
    {
      if ($remove_lines !== NULL && !is_numeric($remove_lines))
      {
        $remove_lines = 0;
      }

      settype($remove_lines, 'integer');

      $doc_root = realpath($_SERVER['DOCUMENT_ROOT']);
      $doc_root .= (substr($doc_root, -1) != DIRECTORY_SEPERATOR) ? DIRECTORY_SEPERATOR : '';

      if ($backtrace === NULL)
      {
        $backtrace = debug_backtrace();
      }

      while ($remove_lines > 0)
      {
        array_shift($backtrace);
        $remove_lines--;
      }

      $backtrace = array_reverse($backtrace);

      $bt_string = '';
      $i = 0;
      foreach ($backtrace as $call)
      {
        if ($i)
        {
          $bt_string .= "\n";
        }
         if (isset($call['file']))
         {
            $bt_string .= str_replace($doc_root, '{doc_root}' . DIRECTORY_SEPARATOR, $call['file']) . '(' . $call['line'] . '): ';
         } else
         {
            $bt_string .= '[internal function]: ';
         }
         if (isset($call['class'])) 
         {
            $bt_string .= $call['class'] . $call['type'];
         }
        if (isset($call['class']) || isset($call['function'])) 
        {
          $bt_string .= $call['function'] . '(';
           $j = 0;
          if (!isset($call['args'])) 
          {
            $call['args'] = array();
          }
          foreach ($call['args'] as $arg)
          {
            if ($j)
            {
                $bt_string .= ', ';
            }
            if (is_bool($arg))
            {
                $bt_string .= ($arg) ? 'true' : 'false';
            } elseif (is_null($arg)) 
            {
                $bt_string .= 'NULL';
            } elseif (is_array($arg))
            {
               $bt_string .= 'Array';
            } elseif (is_object($arg))
            {
                $bt_string .= 'Object(' . get_class($arg) . ')';
            } elseif (is_string($arg)) 
            {
                // Shorten the UTF-8 string if it is too long
                if (strlen(utf8_decode($arg)) > 18)
                {
                    // If we can't match as unicode, try single byte
                    if (!preg_match('#^(.{0,15})#us', $arg, $short_arg))
                    {
                        preg_match('#^(.{0,15})#s', $arg, $short_arg);
                    }
                    $arg  = $short_arg[0] . '...';
                }
                $bt_string .= "'" . $arg . "'";
            } else 
            {
                $bt_string .= (string) $arg;
            }
        }
            $bt_string .= ')';
        }
        $i++;
       }       
      return $bt_string;
    }  // end of the backtrace function


    /****
    *
    * Performs a [http://php.net/call_user_func call_user_func()], while translating PHP 5.2 static callback syntax for PHP 5.1 and 5.0
    *
    ****/

    static public function call($callback, $parameters=array())
    {
        //Fix PHP 5.0 and 5.1 static callback syntax
        if (is_string($callback) && strpos($callback, '::') !== FALSE)
        {
            $callback = explode('::', $callback);
        }

        $parameters = array_slice(func_get_args(), 1);
        if (sizeof($parameters) == 1 && is_array($parameters[0]))
        {
            $parameters = $parameters[0];
        }

        return call_user_func_array($callback, $parameters);
    }

    /****
    *
    * Translates a Class::method style static method callback to array style for compatibility with PHP 5.0 and 5.1 and built-in PHP functions
    *
    ****/

    /****
    *
    *   Checks an error/exception destination to make sure it is valid
    *
    ****/
    static private function checkDestination($destination)
        {
            if ($destination == 'html') {
                return 'html';
            }

            if (preg_match('~^(?:                                                                         # Allow leading whitespace
                               (?:[^\x00-\x20\(\)<>@,;:\\\\"\.\[\]]+|"[^"\\\\\n\r]+")                     # An "atom" or a quoted string
                               (?:\.[ \t]*(?:[^\x00-\x20\(\)<>@,;:\\\\"\.\[\]]+|"[^"\\\\\n\r]+"[ \t]*))*  # A . plus another "atom" or a quoted string, any number of times
                              )@(?:                                                                       # The @ symbol
                               (?:[a-z0-9\\-]+\.)+[a-z]{2,}|                                              # Domain name
                               (?:(?:[01]?\d?\d|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d?\d|2[0-4]\d|25[0-5])    # (or) IP addresses
                              )
                              (?:\s*,\s*                                                                  # Any number of other emails separated by a comma with surrounding spaces
                               (?:
                                (?:[^\x00-\x20\(\)<>@,;:\\\\"\.\[\]]+|"[^"\\\\\n\r]+")
                                (?:\.[ \t]*(?:[^\x00-\x20\(\)<>@,;:\\\\"\.\[\]]+|"[^"\\\\\n\r]+"[ \t]*))*
                               )@(?:
                                (?:[a-z0-9\\-]+\.)+[a-z]{2,}|
                                (?:(?:[01]?\d?\d|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d?\d|2[0-4]\d|25[0-5])
                               )
                              )*$~xiD', $destination)) {
                return 'email';
            }

            $path_info     = pathinfo($destination);
            $dir_exists    = file_exists($path_info['dirname']);
            $dir_writable  = ($dir_exists) ? is_writable($path_info['dirname']) : FALSE;
            $file_exists   = file_exists($destination);
            $file_writable = ($file_exists) ? is_writable($destination) : FALSE;

            if (!$dir_exists || ($dir_exists && ((!$file_exists && !$dir_writable) || ($file_exists && !$file_writable)))) {
                return FALSE;
            }

            return 'file';
        }





  } // End of class


?>
\$\endgroup\$
2
  • \$\begingroup\$ Erm, 404 Not Found. \$\endgroup\$ – Kerri Shotts Jun 18 '11 at 5:05
  • \$\begingroup\$ Please post code, not just links to code. See the FAQ for more information. \$\endgroup\$ – Tim Martin Jun 21 '11 at 8:38
12
\$\begingroup\$

I haven't read the source code entirely, but here a few things that came to mind immediately:

  • Use PHP Docblocks, so my IDE can support me when using your code
  • Please break down backtrace() into smaller functions which are understandable in an instant or insert some inline comments above those crazy if/else/string operations in this function.
  • Omit the closing ?> when you have a PHP only file, because it might give you alot of headaches (weird spaces popping up in your HTML output which you won't find easily)
  • Make __construct and __clone (even if they don't contain any code) private if you have a static class. This way somebody who uses your class and doesn't bother to look into the source or docs will realize how to use your class faster.
  • Don't use String concatenation (.=) in a loop. Build some kind of data structure like an array within this loop and implode() afterwards. Much easier to understand and faster since concatenating strings is very expensive.
  • If you want other people to use and maintain your code, please provide at least better description what this code does, some sample usage and output.
\$\endgroup\$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.