Archive

Posts Tagged ‘error’

Convert A String To A Date Value In MySQL

April 21st, 2009 No comments

There are numerous ways to print out dates and times, and many hours of programming are spent in converting dates from one format to another.

To do this in MySQL you use the STR_TO_DATE() function, which has two parameters. The first parameter is the time to be parsed and the second is the format of that time. Here is a simple example that converts one date format to a MySQL formatted date string.

SELECT STR_TO_DATE('[21/Apr/2009:07:14:50 +0100]', '[%d/%b/%Y:%H:%i:%S +0100]');

This outputs 2009-04-21 07:14:50.

Using this function is quite intuitive and means that you can convert between time formats very easily. Here are a few more examples of this function.

SELECT STR_TO_DATE('21/04/2009', '%d/%m/%Y'); // 2009-04-21
SELECT STR_TO_DATE('04/21/2009', '%m/%d/%Y'); // 2009-04-21
SELECT STR_TO_DATE('2009-04-21 14', '%Y-%m-%d %H'); // 2009-04-21 14:00:00

If you enter a date that can’t be translated then you will get an error, take the following code that tries to convert a minute value of 87.

SELECT STR_TO_DATE('2009-04-21 14:87', '%Y-%m-%d %H:%i');

The following error message is returned.

Incorrect datetime value: '2009-04-21 14:87' for function str_to_date

This error can be quite easy to reproduce. For example, if you wanted to parse a time that was in 24 format, you would use the %H for hours. Using the %h value for hours will produce exactly this error.

The following table lists all of the different parameters that are involved in the date formatting features within MySQL. Use this to parse your own dates.

Specifier Description
%a Abbreviated weekday name (Sun..Sat)
%b Abbreviated month name (Jan..Dec)
%c Month, numeric (0..12)
%D Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)
%d Day of the month, numeric (00..31)
%e Day of the month, numeric (0..31)
%f Microseconds (000000..999999)
%H Hour (00..23)
%h Hour (01..12)
%I Hour (01..12)
%i Minutes, numeric (00..59)
%j Day of year (001..366)
%k Hour (0..23)
%l Hour (1..12)
%M Month name (January..December)
%m Month, numeric (00..12)
%p AM or PM
%r Time, 12-hour (hh:mm:ss followed by AM or PM)
%S Seconds (00..59)
%s Seconds (00..59)
%T Time, 24-hour (hh:mm:ss)
%U Week (00..53), where Sunday is the first day of the week
%u Week (00..53), where Monday is the first day of the week
%V Week (01..53), where Sunday is the first day of the week; used with %X
%v Week (01..53), where Monday is the first day of the week; used with %x
%W Weekday name (Sunday..Saturday)
%w Day of the week (0=Sunday..6=Saturday)
%X Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V
%x Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v
%Y Year, numeric, four digits
%y Year, numeric (two digits)
%% A literal % character
%x x, for any x not listed above
Categories: MySQL Tags: , , , , , , ,

A Useful Error Controller Class For Zend Framework Applications

December 23rd, 2008 7 comments

One useful function of any application is to report on any errors that occurred. Zend Framework comes with a nice error controller system that you can activate by creating an ErrorController class.

The following is an ErrorController class that I use. It detects what sort of error occurred and displays a message to the user. It will also email a detailed report of the error to the server admins.

class ErrorController extends Zend_Controller_Action
{
  public function errorAction()
  {
    // Ensure the default view suffix is used so we always return good
    // content
    $this->_helper->viewRenderer->setViewSuffix('phtml');
 
    // Grab the error object from the request
    $errors = $this->_getParam('error_handler');
 
    switch ($errors->type) {
      case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
      case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
        // 404 error -- controller or action not found
        $this->getResponse()->setHttpResponseCode(404);
        $this->view->message = 'Page not found';
        $this->view->code  = 404;
        if ($errors->type == Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER) {
          $this->view->info = sprintf(
                      'Unable to find controller "%s" in module "%s"',
                      $errors->request->getControllerName(),
                      $errors->request->getModuleName()
                    );
        }
        if ($errors->type == Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION) {
          $this->view->info = sprintf(
                      'Unable to find action "%s" in controller "%s" in module "%s"',
                      $errors->request->getActionName(),
                      $errors->request->getControllerName(),
                      $errors->request->getModuleName()
                    );
        }
        break;
      case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
      default:
        // application error
        $this->getResponse()->setHttpResponseCode(500);
        $this->view->message = 'Application error';
        $this->view->code  = 500;
        $this->view->info  = $errors->exception;
        break;
    }
 
    // send a mail to let someone know that there was a problem!
    $config = Zend_Registry::get('configuration');
    $tr = new Zend_Mail_Transport_Smtp($config->smtp);
    Zend_Mail::setDefaultTransport($tr);
 
    $mail = new Zend_Mail();
    $emailBody = "An error occurred in the system. The error message contained the following output:\n\n";
    $emailBody .= $this->view->message." (".$this->view->code.")\n\n";
    $emailBody .= "Zend Error Type: ".$errors->type."\n\n";
    $emailBody .= "REQUEST_URI: ".$_SERVER['REQUEST_URI']."\n\n";
    if ( isset($_SERVER['HTTP_REFERER']) ) {
      $emailBody .= "HTTP_REFERER: ".$_SERVER['HTTP_REFERER']."\n\n";
    }
    $emailBody .= "Stack trace: \n\n". $errors->exception->getTraceAsString()."\n\n";
 
    // find the user to blame!
    $username = Zend_Auth::getInstance()->getIdentity();
    $emailBody .= "This error was created by ".$username.".";
 
    $mail->setBodyText($emailBody);
    $mail->setFrom('anAddress@example.com', '');
    $mail->addTo($config->adminEmail, $config->adminName);
    $mail->setSubject('An Error Occured');
    // Email
    $mail->send();
 
    $this->view->title = 'Error!';
    $this->view->heading = 'Error!';
 
    // pass the environment to the view script so we can conditionally
    // display more/less information
    $this->view->env   = $this->getInvokeArg('env');
 
    // pass the actual exception object to the view
    $this->view->exception = $errors->exception;
 
    // pass the request to the view
    $this->view->request = $errors->request;
  }

This error controller relies on certain options that have been set up in your configuration file. Add the following options to your configuration file to get these options working.

smtp = my.smtpserver.com
adminEmail = admin@example.com
adminName = 'Your name'

To enable this just call the throwExceptions() function of the Zend_Controller_Front and pass it a value of false. This will cause the framework to look for an error controller rather than try to print out things.

$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(false);

Finally, you need to add a view so that your errors will be displayed nicely. This will display more if the environment is set to 'test'.

<h3>Error has happened. Inside this application. Sorry about that.</h3>
<p><?=$this->message ?> (<?=$this->code ?>) </p>
<?
if( $this->env == 'test' ) {
 if ( isset($this->info ) ) { ?>
<? if ( 404 == $this->code ) { ?>
  <p><b>Reason:</b> <?= $this->info ?></p>
<? } elseif (500 == $this->code) { ?>
  <p>Bad server, naughty server!<br />No donut for you!</p>
  <p><img src="<?=$this->baseUrl();?>/images/donut.jpg" /></p>
  <h4>Exception information:</h4>
 <p><b>Message:</b> <?= $this->info->getMessage() ?></p>
 <h4>Stack trace:</h4>
 <pre><?= $this->info->getTraceAsString() ?></pre>
<? } ?>
<? } ?>
<? } ?>

Quickly Run Any PHP Code Through A Form

October 15th, 2008 No comments

NOTE: This bit of code is potentially very dangerous and should NOT be uploaded to your web host. I only use this function on my localhost to quickly check that a snippet of code works.

If you want to quickly run some PHP code, and don’t want to have to go through creating a file just to see the outcome of a simple calculation is then this snippet might be of some use to you.

It works by taking the contents of the textarea and creating a file with the filename of 'tempcodefile.php', which contains that code. The created file is then included in order to run the code, the output of which is displayed at the top of the screen.

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
<html>
<head>
<title>PHP Tester</title>
</head>
<body>
<?php
 if (isset($_POST["code"])) {
  $code = $_POST["code"];
  $file = fopen('tempcodefile.php', 'w');
  fwrite($file, $code);
  require_once('tempcodefile.php');
 } else {
  $code = "";
 }
?>
<form action='<?php echo $_SERVER["PHP_SELF"]; ?>' method='post'>
<div style='text-align:center'>
<textarea rows="30" cols="150" name="code"><?php echo $code; ?></textarea>
<br />
<input type="submit" value="Run" />
</div>
</form>
</body>
</html>

To run this code enter some PHP code (including the <?php and > PHP brackets) into the text box and click on the run button.

<?php echo 1+1; ?>

The first time the form is run a file will be created containing this code, and the output "2" will be printed at the top of the screen. Error reporting is turned on and errors are displayed at the start of the script so if you enter something that doesn’t work it will tell you about it.

This script is useful if you just want to run something quickly, but beware that if you upload this to your web server you are at risk of someone running some code that will delete all the files on your site.

Categories: PHP Tags: , , , , ,

PHP Version Not Specified Warning In CodeSniffer

October 13th, 2008 2 comments

In my last post I talked about the PHP CodeSniffer, so today I thought I would solve a common problem that doesn’t seem to have any documentation. Whilst correcting a class file I had there was this one warning that just wouldn’t go away.

FILE: myclass.php
--------------------------------------------------------------------------------
FOUND 0 ERROR(S) AND 1 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
11 | WARNING | PHP version not specified
--------------------------------------------------------------------------------

There is no documentation (that I could find) on the CodeSniffer site about how to solve this, so I dove into the source files for the CodeSniffer extension and found this line.

* PHP Version 5

Add this to the file docs at the top of your file. You can change the version to be more specific if you wish, so if your class required at least PHP version 5.0.1 then use this as the version. I hope this little snippet helps someone.

Write PHP Standards Compliant Code With PHP CodeSniffer

October 13th, 2008 1 comment

One of the biggest problems I have found with PHP is the reputation that it gets. This is due to the amount of abuse that the language undergoes by many developers every day. They write code that works, and is efficient, but trying to figure out what it does can take hours as there are no comments, and the code is generally written in any old way. PHP is quite lenient with regards to how code is written.

This is where CodeSnigger comes in. CodeSniffer is a PHP5 script that goes through any PHP (or JavaScript) file that you give it and detects coding violations from a defined set of coding standards. These standards start out with the simple things like using spaces instead of tabs (due to the way in which tabs are displayed differently on different computers) to the more complex things like prefixing private variables with an underscore.

Because CodeSniffer is part of the PEAR framework you can install it using pear commands. As long as PEAR is installed you can use the following command to install CodeSniffer.

pear install PHP_CodeSniffer

If everything has worked you should find a file in your PHP folder called phpcs.bat. You can then use this file to run against your PHP scripts. Here is what to do if you want to run this file against a file.

phpcs class.MyClass.php

This produces something like the following output. I’m not going to reproduce it all as there are quite a few errors.

FILE: class.MyClass.php
--------------------------------------------------------------------------------
FOUND 165 ERROR(S) AND 35 WARNING(S) AFFECTING 123 LINE(S)
--------------------------------------------------------------------------------
1 | ERROR | End of line character is invalid; expected "\n" but found
| | "\r\n"

If you want to check an entire directory then just type in the path to the directory.

phpcs /path/to/file/

This will check each file in turn and produce output.

I thought I was pretty consistent with my coding, but after testing a simple 200 line class I found over 165 errors and 35 warnings for all sorts of things. The main complaint was my use of tabs instead of spaces, for which I can only blame my editor. However, there were a lot of other things such as aligning equals signs with equals signs on other lines.

Using this tool will help you write more understandable code, but will also spot certain syntax errors before they go live. It is good practice to use this tool on your code before you commit your changes as it can prevent you from making silly mistakes like leaving the semi-colon from the end of a line.