Monday, December 7, 2009

MySQL: Error 1305 - Function xxx does not exist

I ran into an odd issue on a project I updated awhile ago. I updated an existing sql statement to include IFNULL for an exclusion check. It worked fine on my dev machine, but caused an issue on the production machine.

The version of MySQL on my dev machine was a little bit newer than production so the issue never came up. Here is the error the sql server returned:
#1305 - FUNCTION [DATABASE_NAME].ifnull does not exist

Here is a little bit of the sql that caused the error:
AND IFNULL ( `tbl_category_admin`.`admin_key_id` =5, true )

The problem was caused by the space between IFNULL and (. Changing it to IFNULL( solved the problem. If you run into an issue where MySQL returns an error saying a given function does not exist look for spaces between the function and the "(".

Labels: , , , , ,

Sunday, October 11, 2009

PHP: Creating your own custom ini config file

In a continuing effort to make my life more difficult I've decided to write my own MVC. I could have easily used one of many frameworks(Zend Framework, Cake, Symfony, etc ...) but I was really interested in what it takes to write one. So far it's been a great experience and I've learned a lot about PHP5.

One of the things I noticed about a lot of the MVCs is they store settings in an external ini file. I had no idea how they pulled the information out of them until I ran across this article on IBM's website. They mentioned a function called parse_ini_file. This function has been around since PHP4, but I never knew about it. You could fill the grand canyon with the things I don't know, but let's focus on this for now.

This function allows you to read a external ini file and it returns an array of properties. You can also configure it to return an associative array of values grouped by category.

This allowed me to move a lot of settings into an external file and clean up a huge chunk of code. The problem is many of the variables I defined were dynamic. parse_ini_file doesn't evaluate external PHP code. The trick to that is to run eval on things you want it to parse.

Here is an example of some code I have stored in an external file.
[define]
PATH_HTTP = "http://{$_SERVER['HTTP_HOST']}/test_site/"

I created a function that will parse the ini file and will run eval on anything in the define group.
//configure define. this will parse php code
if(isset($ini['define']))
{
  foreach($ini['define'] as $key=>$item)
  {
    define($key, eval("return \"{$item}\";"));
  }
}

The important part to note when using eval is that it doesn't return a value. If you want to capture the evaluated variable prefix the variable with "return" and make sure to end the line with a ;.

Update
An important thing to note is that ini files can be read very easily in a web browser. You'll want to set up a .htaccess file that blocks viewing of ini files. You can copy-paste this into a .htaccess file at the root of your site.
<files *.ini>
order allow,deny
deny from all
</files>

Labels: , , , , , , ,

Sunday, October 4, 2009

Zend Studio 6.1: SVN update on Snow Leopard

I ran into an issue with a svn project today so I decided to create a new repository. The thing I didn't realize is that SVN has been upgraded to version 1.6.2 in Snow Leopard. This caused a major conflict with Zend Studio 6.1. When I tried to browse the repository with a project import it couldn't read the SVN tree.

After a lot of searching I figured out how to update the SVN plug-in.

Goto Help => Software Updates => Find and Install.
Select Search for updates of the currently installed features and click Finish.

When the search finishes check "Subversive update site 2.0.x".



Click the "Search" button. There should be an option listed called "Subversive update site 2.0.x". If you check the box you will get an error on a JavaHL 1.4.5 Win32 Binaries (Optional). Click the arrow to the left of to expose more options. Click the arrow to the left of "Subversive SVN Connectors" and uncheck all the JavaHL Win32 Binaries. This should allow you to install the new update.



When the update has finished Zend will prompt you to allow a restart. Once it closes you will have to restart it. You'll need to select the new SVN plugin. Goto Zend Studio for Eclipse => Preferences. Goto Team => SVN. Click the SVN Connector tab and select "SVN Kit (SVN/1.6.2 SVNKit/1.3.0)" from the SVN Connector down down.



You should be able to import a project from a new version of SVN without a problem.

Update 10/05/2009
I may have left out a key piece of resolving the SVN issue. I was trying many things at the time, and this might be one of the parts that made it work.

There is a new version of the SVNKit plug-in for eclipse. I don't have the exact steps at this moment to install them in Zend Studio, but the site has the steps for Eclipse and they're pretty close. You can view them here.

Labels: , , , , , , , , , ,

Saturday, September 19, 2009

PHP: Simple register_globals workaround

Working with an old php4 project in php5 can expose some bad programming practices and create bugs. The first problem is relying on register_globals. I don't want to turn this on because it injects variables into the page scope. I also don't want to update the whole project to not rely on it.

The simple way around this is to write something that injects the variables into the project scope. This function will read all the variables from the url and inject them into the project scope. You should never rely on register_globals, but if you don't want to update old code this is an easy workaround.

function register_globals()
{
  //if register_globals is on then return
  if(ini_get("register_globals")) return;

  //inject URL vars into scope
  foreach($_REQUEST as $key=>$item)
  {
    $GLOBALS[$key] = $item;
  }
}

Labels: , , , , , , , ,

MAMP (Pro): Making changes to php.ini

I'm using MAMP Pro and trying to get an old project built in PHP4 up and running. The project depends on register_globals to be turned on. I tried to update the php.ini file located in MAMP/conf/php4/php.ini, but nothing would change when I looked at the phpinfo() output.

After banging my head against the wall for awhile I turned to the forums at mamp.info. There is an importance difference between MAMP and MAMP PRO. If you want to update any of the ini file settings while using MAMP PRO goto File => Edit Template and select the ini you want to update.

The full forum post can be found here.

Labels: , , , , , , , , , , , , , ,

Wednesday, July 22, 2009

PHP: Error logging

Work with other languages has exposed me to new ways of logging errors and/or debugging code on web pages. I'm not sure how most php developers log errors or debug code so I can only guess it was similar to the way I would do it. By that I mean using echo in the middle of some HTML. It gets the job done, but it's kinda ugly.

I've since started using a cleaner method of logging errors. It's not as robust as a class, but it's better than throwing code out on a page. I've started using the error_log function wrapped in another function to control when it should output the error to a log.


function debug($allow_debug, $msg)
{
if($allow_debug)
{
error_log($msg."\n", 3, '/path/to/phperror.log');
}
}

When the function is used I pass a boolean that states wither I want the error passed out to the log. Typically I would set a variable at the top of the script and pass it into each instance of debug.

error_log takes three parameters. The first is the message that I want to pass out to the log. The important part on this input is the line return. That way each error starts on a new line. The second is the type of message I'm logging. The third is the location of the log file. Make sure it has the correct permissions so PHP can write to it.

You can view more information on error_log here.

Labels: , , , , , , ,

Wednesday, February 13, 2008

PHP: Code snippet

I found this on a page written in japanese. Great for streaming files through php and not reveling their source.
http://phpspot.org/blog/archives/2008/02/phpdlphp.html

header('Content-Type: application/octet-stream');
header('Content-Disposition: filename=dl.zip');
header('Content-Length: '.filesize('dl.zip'));
echo file_get_contents("dl.zip");
?>

This will also post the size of the file so you know how long it will take for it to download.

Labels: , , , , , , ,