Non-abstract method Foo::bar() must contain body

I was working on one of my PHP based projects, and I was getting the following error:

Non-abstract method Foo::bar() must contain body in Foo.php on line 10

The problem was that I had accidentally put a semicolon at the end of the first line of the function:

WRONG WAY:

  
class Foo 
{ 
    function bar(); // extra semicolon! 
    { 
        // stuff 
    } 
}

RIGHT WAY:

  
class Foo 
{ 
    function bar()    // no semicolon, yay 
    { 
        // stuff 
    } 
}

Letting the database to the heavy lifting: Capitalization via SQL

Years ago I had the pleasure of meeting Ben Forta and listen to his thoughts on web development. One thing that stuck with me was his statement that:

“Dynamic programming languages like PHP and Coldfusion are great, but developers need to leverage the database more. Allow the database to do it’s job, the heavy lifting”

With that being said, I was recently working with a database that contained users first names. The data was not snantized at entry, and contained a mix of lower cased (ex. josh) and upper cased (ex. Josh) first characters in the firstname column. I needed to always present the users first name in a capitalized format.

The first solution that most developers would reach for is dynamically parsing the users first name, then upper-casing the first character. This works, but in my opinion isn’t the most elegant solution.

With a simple SQL statement, like the one below, we can return the users first name already in a capitalized state.

SELECT (UPPER(LEFT(firstname,1))+SUBSTRING(firstname,2,LEN(firstname))) as firstname 
FROM users
It’s quick to implement, its easy to work with, and it’s also very fast on the performance scale.
Yes, I understand that there are cool convenience functions in like ucfirst() in PHP, but I’m a lazy programmer and I don’t want to have to remember to use ucfirst() every time I’m dealing with the users name. I’d rather get the information in the correct format the first time, then remembering to groom it every time before I use it. Set it and forget it.

PHP and cURL in parallel

I was recently working on a php based project for a client. I needed to pull in content from 10 different URLs, then process that data into something useful.

I have a growing love affair with cURL, so it was my natural selection for the project.

In my first approach, I looped over the list of URLs, sent the cURL request, wait for the response, stored the data. repeat until done.

That worked, but it was very slow process. The page was taking between 30 – 45 seconds to load. That doesn’t sound long, but in terms of web applications, that’s an eternity.

I tried several tricks to speed the application up, but the bottle neck was the cURL calls. Each call was done in a synchronous manner. Every call to cURL had to be completed before the next could be made.

After doing to research on how to speed this up, I came across the following php cURL functions:

curl_multi_init();
curl_multi_add_handle();
curl_multi_select();
curl_multi_exec();
curl_multi_getcontent();
curl_multi_info_read();
curl_multi_remove_handle();

Using these methods allow for cURL to send asynchronous requests, solving my pervious problem.

A little more searching, and I found an awesome wrapper library that takes the guesswork out of the using the curl_multi methods. “ParallelCurl” https://github.com/petewarden/ParallelCurl

The sample code provided with the library was very straight forward and super easy to use.

After using asynchronous cURL calls via the ParallelCurl library, I was able to reduce the page load time from 45 seconds to 15 seconds. It’s still slow, but it’s a HUGE improvement, and it makes the application usable, and reduces load on my server. It’s a win-win-win situation!

Using cURL and PHP to upload files through a form post

Lately I have been working on a project that requires me to use PHP to interact with a REST based service. cURL is the logical choice for making HTTP calls to the REST service.

I love cURL, I’ve blogged about it before, but I recently ran into some major issues.

The REST service I was using required me to send two files along with some meta information. easy enough. I used the following code:

$postFields = array();

//files
$postFields['file'] = "@$filePath";
$postFields['thumbnail'] = "@$thumbnailPath";

//metaData
$postFields['title'] = "$title";
$postFields['description'] = "$description";
$postFields['tags'] = "$tags";
$postFields['licenseinfo'] = "$licenseinfo";
$postFields['token'] = "$userToken";

$curl_handle = curl_init();

curl_setopt($curl_handle, CURLOPT_URL, $api_url);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_handle, CURLOPT_POST, true);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $http_post_fields);

//execute the API Call
$returned_data = curl_exec($curl_handle);

The code worked great, sending an “at” sign (@) before the file path makes sure that cURL sends the file as part of a “multipart/form-data” post. Exactly what we needed.

The form post from cURL worked great, but the REST service was retuning a 400 error and saying “The specified thumbnail file is not supported.”. I was at a loss. The service documentation stated the “jpg, jpeg, gif, and png” files were supported.

I ended up contacting the developers of the service who told me that the content type for the file had to be set to “image/jpg” (for jpg).

After pouring through the cURL documentation and not finding anything about how to set the content type for a single file in a “multipart/form-data” post, I turned to Goolge. My searches with about as helpful as the cURL docs. I sent a few hours hacking my code and trying some things, I ever read some posts from 2008 saying that is was not possible to do. Then, I got a break through, a single ray of light. On a message board was a single sentence replay. “You should try this… $image;type=image/jpg”.

That was the break through I needed. Below is final updated code:

$postFields = array(); 

//files
 $postFields['file'] = "@$filePath";

//get the extension of the image file
$tumbnailExtention = preg_replace('/^.*\.([^.]+)$/D', '$1', $thumbnailPath);
$postFields['thumbnail'] = "@$thumbnailPath;type=image/$tumbnailExtention";

//metaData
$postFields['title'] = "$title";
$postFields['description'] = "$description";
$postFields['tags'] = "$tags";
$postFields['licenseinfo'] = "$licenseinfo";
$postFields['token'] = "$userToken"; 

$curl_handle = curl_init();

curl_setopt($curl_handle, CURLOPT_URL, $api_url);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_handle, CURLOPT_POST, true);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $http_post_fields); 

//execute the API Call
$returned_data = curl_exec($curl_handle);

In summary, if you need to set the content type of a file being sent an image through cURL, via a POST, use the following format:
$postFields[‘file’] = “@PATHTOFILE;type=CONTENTTYPEHERE”;

Removing trailing comas with PHP

php_logo_mediumDealing with trailing comas in lists is common problem for developers. I found the best way to handle this situation in PHP is with the following regular expression.

$string = eregi_replace(',$', '', $string);

Before: string = “2, 6, 9,”
After:
string = “2, 6, 9”

Only the trailing coma will be stripped. If no coma is found, the string simply passes through. It’s a simple and effective solution.