PHP

PHP Function to Connect via FTP with Retry Capability

Posted in PHP, Web Development on February 21st, 2012 by Steve Marks – Be the first to comment

Let’s face it… If something can go wrong, it will go wrong. This is no exception for FTP connections either. Maybe the remote server is not accessible, the network is down, or the connection times out.

PHP comes with a set of useful functions to deal with common FTP operations. What I want to show you in this post however is, in conjuntion with these functions, how to improve the connection aspect and add a failsafe should a connection not be available. I find this especially effective for scripts left running as a background process.

Let’s take a look at the function:

function connect_to_ftp($ftp_host, $ftp_user, $ftp_pass, $retries)
{
	$connected = false;
	$retry = 0;

	// Keep looping until connected or met no. of retries if $retries is not zero
	while (!$connected && ($retries==0 || ($retries>0 && $retry<$retries)))
	{
		// try connecting to host
		$ftp_conn = ftp_connect($ftp_host);

		if ($ftp_conn)
		{
			// connection was successful. now try to login
			$ftp_login = ftp_login($ftp_conn, $ftp_user, $ftp_pass);

			if ($ftp_login)
			{
				// login was successful. let's get outta here...
				return $ftp_conn;
			}
			else
			{
				echo "Unable to login to ".$ftp_host." using ".$ftp_user.":".$ftp_pass."\n";
			}
		}
		else
		{
			echo "Unable to establish FTP connection to ".$ftp_host."\n";
		}

		sleep(5); // sleep for 5 seconds before trying again

		$retry++;
	}

	return $ftp_conn;
}

And an example of using the function:

// initialise FTP connection details
$ftp_host = 'ftp.mysite.com';
$ftp_user = 'username';
$ftp_pass = 'password';
$retries = 0; // Number of maximum retries. Set to 0 for unlimited

// returned is an FTP connection as a resource for use in other functions
$ftp_conn = connect_to_ftp($ftp_host, $ftp_user, $ftp_pass, $retries);

echo 'FTP Connection: '.$ftp_conn;

Share

How to Fix IE8 Error “Unable to download X.php from yoursite.com”

Posted in PHP, Web Development on February 9th, 2012 by Steve Marks – Be the first to comment

Rarely do I hear the words “Internet Explorer” and “Error” mentioned in the same sentence. Alright… maybe that’s a bit of a lie. Unfortunately however, few us can control what browsers our users are using so we have to try and cater for all instances. The one I’m going to talk about today is specific to IE8 and occured when trying to force the download of a PDF to the browser in a PHP script.

The error reads as follows:

Unable to download somefile.php from yoursite.com.

Internet Explorer was unable to open this site. The requested site is
either unavailable or cannot be found. Please try again later.

After looking into the problem it turned out that the problem was down to the PHP headers being sent when outputting the file, inparticular the ‘Cache-Control’ header. If this header is not being set, or is not being set correctly you can start to experience problems.

The Solution

Previously I wasn’t using the aforementioned ‘Cache-Control’ header but apparently setting it to ‘no-cache’ or ‘no-store’ will have the same negative effect. For me the answer was to set it to ‘private’ or to set it with a blank value. Like so:

header("Cache-Control: private");

Or:

header("Cache-Control: ");

The site in question was also being used over SSL but I’m not sure if this also played a role. Regardless, the above worked and it kept our IE8 users happy.

Share

Loop Through Letters in a String with PHP

Posted in PHP, Web Development on September 23rd, 2011 by Steve Marks – Be the first to comment

Iterating through a string to get each letter can be easily achieved with PHP. The example below shows how this can be done with a for loop:

$string = "HelloWorld";

for ($i=0; $i<strlen($string); $i++) {
    echo $string[$i].".";
}

// Outputs: H.e.l.l.o.W.o.r.l.d.

Notice how we reference the individual letters like we would an array element. This also means we can get the letter at a certain point by referencing the letters index like so:

$string = "HelloWorld";

echo $string[4];

// Outputs: o

Share

PHP Benchmark – sha1_file() vs sha1(file_get_contents())

Posted in PHP, Web Development on September 16th, 2011 by Steve Marks – Be the first to comment

When working on a recent project the need came up to produce a SHA1 hash of a file to allow comparisons between new and existing files. I knew that I could easily create a hash of a file using PHP’s sha1_file() function but I was unsure on the performance and speed of it, bearing in mind that this process would need to be done hundreds of times a day.

I’d seen other developers on forums mention that the same result could be acheived using a combination of the sha1() and file_get_contents() functions but there was no mention of whether it would be quicker, slower, or if indeed it was essentially the same thing. As a result I decided to pit the two methods against each other to see how each performed individually.

Let The Tests Begin…

My testing script looked a little like the following:

echo microtime(true)."\n";

for ($i=0; $i<1000; $i++) {
	$output = sha1_file($file);
}

echo microtime(true)."\n";

for ($i=0; $i<1000; $i++) {
	$output = sha1(file_get_contents($file));
}

echo microtime(true);

I ran the script for two different files located in the same directory as the script; one that was 213 KB and a slightly larger one at 1.52 MB. The script was ran 5 times for each file and average time differences taken at the end.

The Results

File 1 - 213 KB

sha1_file() average time - 1.25498 seconds
sha1(file_get_contents()) average time - 1.21908 seconds

File 2 - 1.52 MB

sha1_file() average time - 8.4037 seconds
sha1(file_get_contents()) average time - 8.89108 seconds

The Conclusion

As you see from the results above the method speeds differ based on the size of the file being hashed. For smaller files the second method was faster, but for larger files the sha1_file() was the preferred option. Remember that these tests contained a thousand iterations each so the time difference between the two is minimal, however I feel it does become an important factor when you'll be repeating this process thousands of times, over and over again.

It's also worth noting that this wasn't a fluke. I repeated the same tests three more times with the same files and the outcome was the same.

Share

Capturing and Handling PHP Errors Gracefully

Posted in PHP, Web Development on September 6th, 2011 by Steve Marks – 1 Comment

Capturing errors are essential in reducing bugs and debugging PHP code. Whether it’s a simple undefined variable or a more complex memory allocation error, it’s important that you are made aware of these errors. Not only that but if a frontend user sees an error, or if something doesn’t work as it should, it can instantly effect their view of your website or application, sometimes even putting them off enough to move on elsewhere. Remember that even though you’ve tested your code thoroughly there will always be a scenario that you haven’t tested. You can be sure that if there’s an error a user one day will find it.

Another scenario I ran into recently was where a script was running silently as a background process. Due to a fatal error somewhere whilst it was running the script stopped suddenly and, due to it running silently I was unaware that anything had gone wrong for a good few hours.

So, how do we capture these errors? Allow me to show you…

The Solution

To deal with these errors appropriately I’m going to use two PHP functions; register_shutdown_function() and error_get_last().

The first function, register_shutdown_function(), allows us to specify a function that will be executed as soon as the PHP script stops running, whether it be from finishing naturally due it coming to the end, or failing because of a fatal PHP error.

The second function, error_get_last(), will pass back the last error, if any, that occured during the running of the script. By putting these two functions together we can create a pretty nifty way of detecting why a script might of failed. Allow me to show you some examples:

Handle All Errors

register_shutdown_function('handleErrors');

function handleErrors() {

   $last_error = error_get_last();

   if (!is_null($last_error)) { // if there has been an error at some point

      // do something with the error
      print_r($last_error);

   }

}

Should an error occur, the above code would output an array containing information about the last error encountered like so:

Array
(
    [type] => 8
    [message] => Undefined variable: myVar
    [file] => C:\www\index.php
    [line] => 24
)

Handle Only Fatal Errors

The above example might be a bit overkill for a lot of developers due to the fact it will return any type of error, including simple undefined errors. What about if we only want to know about fatal PHP errors that caused the script to stop running completely? Then try this:

register_shutdown_function('handleErrors');

function handleErrors() {

   $last_error = error_get_last();

   if (!is_null($last_error) && $last_error['type'] === E_ERROR) { // if there has been a fatal error

      // do something with the error eg. email it, log it somewhere

   }

}

I’ve found that by using the above snippets I’ve managed to iron out lots of bugs and errors that I was completely unaware of. You can bet your bottom dollar that a user wouldn’t report an error if they encountered one so this allows me to act on their behalf and deal with any problems that arise.

Share

Using PHP to Find Files with Name Containing a Wildcard

Posted in PHP, Web Development on August 24th, 2011 by Steve Marks – Be the first to comment

When there’s a need to find files within a directory that contain a specific string or extension we can use the PHP function glob(). This can be particularly useful if, for example, we only want image files that end in ‘_thumb’ or when we want to get a list of all the .txt files in a directory.

An example of the above mentioned examples have been demonstrated below:

// get images containing the string '_thumb'
foreach (glob("*_thumb.*") as $filename) {
	echo $filename."<br />";
}
// get all text files with the extension .txt
foreach (glob("*.txt") as $filename) {
	echo $filename."<br />";
}

The glob() function will return an array of filenames that match the pattern provided allowing you to loop through them and do as you wish.

Share

jQuery .find() Not Working in IE with Dynamic XML File

Posted in Javascript / jQuery, PHP, Web Development on August 23rd, 2011 by Steve Marks – Be the first to comment

This problem arose for me when I was loading markers onto a Google map using their JavaScript API via an AJAX call and a returned XML string generated by PHP. The markers would show in all browsers except IE with no errors or warning messages at all. The script seemed to be failing when looping through the XML using jQuery’s .find() function and after hours of debugging I stumbled across the cause of the issue.

The Solution

Looking back the solution seems pretty darn simple (isn’t that all the way!?!) but with no help from our friend Internet Explorer it took some digging around. It turns out the problem was caused by the content type of the string returned to jQuery by the AJAX call not being set and IE not understanding how to deal with it.

To solve the issue I added the following line just before outputting the XML:

header("Content-Type: text/xml");

After adding the above line the jQuery started to loop through the markers with no problem at all.

Share

Getting the Time a PHP Script Takes to Execute

Posted in PHP, Web Development on July 20th, 2011 by Steve Marks – Be the first to comment

If your working with large resource intensive PHP scripts, or are simply looking to refine and optimize an existing bit of code, one of the steps you might take is to look at how long your PHP code is taking to run. We can do this within the PHP code itself by analyzing the time the script is kicked off and comparing it to the time the script completes.

I’ve included a simple example of this below:

// Place this at the very top of script
$start = microtime(TRUE);

//
// The body of script goes here with lots of wonderful code.
//

// Place this at the very bottom of script
$finish = microtime(TRUE);

// Subtract the start time from the end time to get our difference in seconds
$totaltime = $finish - $start;

echo "This script took ".$totaltime." seconds to run";

The code above uses the function microtime(). This returns the amount of time, including microseconds, since the unix epoch. By adding ‘TRUE’ as a parameter we get the number returned in seconds to the nearest microsecond.

Share

Looping Through an FTP Directory Using PHP

Posted in PHP, Web Development on July 13th, 2011 by Steve Marks – Be the first to comment

If you’re a website developer you’ll probably have countless hours of experience using FTP, from putting sites live, renaming files, deleting files and more. This is made easy through using an FTP client installed on your machine. The process can also be just as simple by using PHP through a whole host of readily available functions when needing to manipulate an FTP directories contents within a PHP script.

Today I want to focus our attention on obtaining and looping through the contents of an FTP directory using PHP through use of the function ftp_nlist(). Let’s take a look at a simple example of how to achieve this:

// Initialise the connection parameters
$ftp_server = "123.123.123.123";
$ftp_username = "ftpuser";
$ftp_password = "ftppass";

// Create an FTP connection
$conn = ftp_connect($ftp_server);

// Login to FTP account using username and password
$login = ftp_login($conn, $ftp_username, $ftp_password);

// Get the contents of the current directory
// Change the second parameter if wanting a subdirectories contents
$files = ftp_nlist($conn, ".");

// Loop through $files
foreach ($files as $file) {

	// Do something with the file here. 

	// For now we'll echo the filenames in a list
	echo $file."<br />";

}

In the above code we are connecting to the FTP server, logging in, obtaining the list of files within the current directory and looping through them.

Share

CodeIgniter Google Static Maps V2 API Library

Posted in PHP, Web Development on July 5th, 2011 by Steve Marks – Be the first to comment

The standard Google Maps JavaScript API is great for making fully functional, interactive maps. A lot of people don’t know however that Google also provide an API for generating static maps in the form of a normal image. This is great if you don’t need all the advanced features available in the JavaScript API, and due to the increased speed are especially useful for mobile websites.

I’ve built a CodeIgniter library for the Google Maps JavaScript API in the past so decided to take up challenge of building a library for the static maps API too. The library and documentation can all be found by following the links below:

Download Library (Last updated 5th July 2011)

View GitHub Repository

View Documentation PDF (74kb)

Demonstrations coming soon…

If you have any questions about the library or would like to leave feedback please leave a comment below or get in touch.

There is more functionality to be added to this library soon so keep checking back for any progress or follow me on GitHub.

Share