Information and howto articles for PHP
PHP is a powerful open source server-sided scripting language that can be used on a wide variety of operating systems and webservers, including Apache on UNIX and IIS on Windows.
PHP contains numerous extensions which enable you to dynamically create images and flash files, parse xml, connect to remote servers using pop, imap, ftp, http and raw sockets, natively access many database servers including PostgreSql, MySQL and Microsoft SQL Server, compress and decompress files, lookup domain names and and much more.
PHP has an excellent manual and online documentation which covers every function for every extension available.
Post sort order: Post Date (Newest First) | Post Date (Oldest First) | Alphabetical | Date Updated
This post has some example PHP code which can be used to work out which error_reporting levels are reported and which are not from an integer value.
I covered how to use PHP's fputcsv without writing to a file in yesterday's post and look at a practical example today: fetching data from MySQL using PDO and sending it to the browser as a CSV, using the fputcsv() function.
PHP's fputcsv function is very useful for creating CSV files, but by default will write out to a file. There are a couple of tricks to be able to keep it all in memory or instead write the CSV data out directly to the web browser without having to write your own custom functions.
We use Zend Lucene Search on a PHP ecommerce website and ran into some issues where records added to the search index from the website interface weren't the same as when created from the command line. It turned out to be a locale issue and setting the locale fixed the problem.
When you go to install PHP on a Debian server, it will attempt to install a whole bunch of Apache packages instead. This is not very useful if you want to install a different web server, or no web server at all.
If you are attempting to get files with a .html extension parsed as PHP with Nginx + php-fpm, you might get an "access denied" error in your browser, and the error message "Access to the script '...' has been denied (see security.limit_extensions)" in your Nginx error log. This post shows how to allow html files to be parsed successfully as PHP with Nginx + php-fpm.
PHP's PDO has a nifty way of fetching database records into an object, but there's a slight gotcha when also using a constructor which initializes the class properties.
If you've got a filename that you need to remove the extension from with PHP, there are a number of ways to do it. Here's three ways, with some benchmarking.
A few days ago, I posted how to temporarily change the auto increment increment in MySQL. This post has an extension class to PHP's PDO to get the current auto increment value, change it to a new value and then reset it back to the original.
After doing an upgrade on my Debian virtual server, which upgraded PHP and Nginx, I got a "502 Bad Gateway" error when browsing websites on that server. This post shows how to fix this problem, and the configuration option to prevent it occurring again on reboot.
Pandora is a music streaming service which can be accessed via a web browser, smartphone/tablet app or desktop app. There is a closed API which can be used to extract some information from Pandora (and edit radio stations etc). This post looks at using a PHP API by Alex Dallaway to access radio stations and bookmarks from Pandora.
PHP has a Reflection API adds the ability to reverse-engineer classes, interfaces, functions, methods and extensions. I needed to use it to get all the publicly accessible properties for a class that aren't static, but there doesn't seem to be a way to get this "out of the box".
I've recently set up a new server with PHP & Nginx using packages from dotdeb. The default upload_max_filesize and post_max_size for this setup with php-fpm is 2M. To adjust it, the Nginx config also needs a configuration change, otherwise you're still stuck with a 2MB limit.
I use phpMyAdmin as a PHP web based manager for MySQL, but find a few of the default configuration options "out of the box" a little annoying. This post shows some useful modifications to the defaults to make phpMyAdmin more usable, in my opinion.
A month ago I posted a PHP email message class for extracting attachments and have been asked by a couple of people how to extract inline images and make it so they can appear in the HTML content of the email. This post shows how to do this, using my email class to get the email.
I've done a bit of work in the past extracting attachments from email with PHP and posted a few articles here showing how to do it. None of them have really been all that satisfactory and so a little earlier this year I started again from scratch. I've posted here what is a work-in-progress due to requests from several people. It's not complete but it does work.
If you have MySQL replication running in either a master-slave or master-master type setup then don't assume everything is running perfectly all the time. Power cuts and other disasters do happen so you need to check periodically to ensure it's all working. This post has a PHP script to check for any MySQL replication errors and then emails if there are any issues
I have a number of batch processes that run using PHP as the command interpreter, and discovered after making a change to one of them the other day that the variables available to PHP in the $_SERVER superglobal are different depending on whether it's run via an SSH session or cron. This post shows the difference on Debian 6. The values available are probably the same on other distros.
The last post looked at how to get a message structure using the PHP IMAP functions into an easier to use flat array. This post looks at how to loop through that array to easily get all the message parts and attachments.
The PHP IMAP functions imap_fetchstructure and imap_fetchbody are used to work out the structure of an email and get the message body and attachments, but they can be fiddly to use because the message parts can be nested. This post has a function which effectively flattens the message parts into a new array, indexed by the part number which can be directly passed to imap_fetchbody.
There may be times when a static variable is needed in a PHP function; static variables maintain their value between function calls and are tidier than using a global variable because they cannot be modified outside of the function.
It's funny when you've been programming in a language for a long time and fall into odd assumptions about particular functions. For some reason I appear to have assumed there was no way to escape characters in PHP's date function. Then yesterday I saw some sample code where a character was escaped and double checked in the manual. Sure enough, you can escape characters and it's obvious. I just thought I'd share it here in case you're making the same mistake I was.
The Simple HTML DOM Parser is a useful tool for extracting content from web pages using jQuery like syntax. If multiple pages are loaded into the parser the available memory will eventually be exhausted and a fatal error will occur.
Sometimes phpMyAdmin is inaccessible and gives the error message "Cannot start session without errors". This can be due to either a client-sided issue with cookies, or a server-sided issue relating to permissions of the temporary directory where session files are stored.
It is possible to fork a process with PHP and have one or more child processes running. If a connection has already been established to a MySQL database and the child processes run queries it's quite likely a "MySQL server has gone away" or a "Lost connection to MySQL server during query" type error will occur.
MySQL supports multiple storage engines which each have their pros and cons; the two most commonly used are MyISAM and INNODB. It's easy to convert a table from one storage engine to another, and this post has a PHP script which convert all tables in a MySQL database from one engine to another.
PHP's include() and include_once() functions can return values to the calling script which can be useful for testing to see if the file was actually included, for example if a configuration file whose filename is based on the website's domain name was included. If no return value is set then it will return integer 1 if included, or boolean false if not.
PHP 5.3 introduced a new error reporting level E_DEPRECATED which is triggered when deprecated functions and methods are used, such as the old style ereg() regular expression functions. This post shows how to suppress E_DEPRECATED error messages.
I was trying to export the structure of a MySQL database using phpMyAdmin but it kept timing out and not showing me the full create script. I think phpMyAdmin uses the information schema to get this information and its on a host with hundreds of databases and tables so querying the information schema runs very slowly. Instead I knocked together a quick PHP script to dump the structure instead and share it here.
The PHP websites I manage email me all notices, warnings and errors and I occasionally get warnings resulting from bots requesting bad URLs. This post looks at a PHP parse_url error caused by an incorrect piece of code that was published which has since been corrected, but there are clearly still scripts out there using the old code and making bad requests.
I posted how to get the keywords from a search engine referer url a while back (here) and from a number of useful comments on that post have completely revised the function which now also supports the query string when it is sent as part of a URL fragment.
I currently develop PHP based websites on a Mac using MAMP. When testing the Interspire Email Marketer API on a local version of a site posting data through to an https:// URL with cURL, I discovered that the version of cURL on MAMP has some issues with certs and SSL.
While trying to debug why something wasn't working, I needed to see what data had been assigned to a Smarty template but from within the template itself (I didn't have time to try and work out where in the PHP code the stuff was assigned and debug from there). This post shows how to do a var_dump or print_r from within the Smarty template itself.
PHP for loops work in the same way as other programming languages and have a useful feature where each expression between the semi-colons can have multiple statements to be executed when separated by a comma. I found this useful myself when I need to have both a zero based and 1 based index in a loop.
I was asked an interesting question by email over the weekend and thought I'd share my response here. The question was "I wish to include in the footer links to my other developed websites. I don't wish to update the footer on each html page every time I create a new webpage. What would be your advice for implementing something like that using html, js and css".
This post shows how to use PHP to extract the keywords searched on by a user when they found your website using a seach engine. Bing, Google and Yahoo are covered here and you can easily add your own to the PHP code supplied.
Just over a year ago I posted how to validate email addresses with PHP using filter_var instead of having to mess around with regular expressions. As pointed out in a comment, chris@example will pass validation; while that is actually a valid email address (the domain part of an email address doesn't actually have to have dots in it, e.g. localhost) in most real situations we don't want it to validate so this post adds a regular expression to the test to ensure the part after the @ contains a dot.
In previous posts I have looked at how to extract images from a web page with PHP and the Simple HTML DOM Parser and generate thumbnails with PHP using a class I created. This page combines the two by downloading all the images from a specified web page and creating thumbnails for them.
PHP supports opening remote URLs (e.g. http://www.example.com/something.htmnl) using the fopen and similar functions. It is possible to disable this function in the PHP configuration so this quick tip shows how to check if it is possible to open remote URLs.
There are many examples and tutorials online about how to generate thumbnail images with PHP but I decided to add another one myself in order to follow up an earlier post titled "extract images from a web page with PHP and the Simple HTML DOM Parser". This post features the class to generate the thumbnail images and the next post will show how to use the Simple HTML DOM Parser to grab all the images from a page and create thumbnails from them.
This post is a response to a question asked on my "Disable PHP in a directory with Apache .htaccess" article asking how to disable PHP completely in Apache, or as it was asked: "Could you tell me how can I turn off PHP on Apache (Run Apache without PHP)".
A little while back I posted how to set cookies with jQuery and was asked about the domain setting and how setting the domain affects sub domains. This post explains how cookies and domains work, and covers some tests I did to check my assumptions were correct.
The PHP CLI (command line interface) allows basic syntax checking of a PHP file. I'll show the basic usage of this in this post and then a couple of ways to check all files in a directory, and all files recursively down the directory tree as posted by a couple of people on Twitter.
If you have a directory which users can upload files into it's a good idea for security reasons to disable server-side parsing of scripts such as PHP. This post shows a couple of options using Apache's .htaccess files.
This is a summary of the posts I've written about PHP's file_get_contents functions when used to download remote content (e.g. webpages, XML files, images etc) and the CURL functions which are used to do the same thing.
Yesterday I looked at how to control browser caching with Apache's mod_expires and today look at how to set the caching/expiry time with headers in PHP to either make sure the resulting data is never cached by the browser, or is cached for a set amount of time.
PHP has several settings for logging errors; in this post I will look at the log_errors and error_log settings which control whether errors should be logged and where to.
PHP's Data Objects, known as PDO, are well covered in the PHP online documentation here but the format of the DSN connection string is covered individually for each driver so I've summarised them here in this post for quick reference.
When temporarily taking down a website to perform maintenance, it's a good idea to return a "503 Service Temporarily Unavailable" header so search engines know to come back later. This post shows how to set this header using an Apache .htaccess file, and also how to show a response page to users with PHP so they know to try again later.
PHP code in a script is commonly delimited by opening <?php and closing ?> tags but there are also the older short open tags like this <? There are instances where you may need to disable short tags as shown in this post and using an Apache .htaccess file.
PHP's PDO database abstraction class offers a better way to connect to databases than the mysql_* etc style functions, or using a 3rd party database library. This post looks at handle errors when connecting and a follow up post later this week will look at how to check for errors when running individual queries after a connection has been successfully established.
This is the final post in my series about PHP exceptions and looks at how when an exception occurs, script execution may continue depending on how the exception is handled.
It's possible to order data randomly with MySQL using ORDER BY RAND() or doing a count on the table and then using LIMIT to choose a random offset. However neither of these are suitable for dealing with large tables with many rows. In this post I present an alternative to these but it does require modifications to the table and additional business logic and is still not perfect.
This post shows how to populate a select box based on the value of the another, by getting JSON data with jQuery from a PHP script that gets the data from a MySQL database.
This post shows how to fetch data from a MySQL database using PHP's PDO library with bound placeholders. This is a fairly basic tutorial and the functions used in it will be used in a post tomorrow titled "Load JSON data with jQuery, PHP and MySQL".
PHP's try..catch can be used to catch multiple exception types. If the try block could cause one of several different exceptions they can each be handled separately with their own catch section.
I've covered how to get the filename and directory name from a full path with PHP before and did include a section which happened to include how to get the filename extension as well, but I continue to find myself unable to remember the name of the function so I've put that part of the previous post into this new one with a title specific to finding the extension.
PHP's Exception object can be extended (just as any class can be that is not declared final) which means different exception types can be thrown that handle the exception differently.
I've posted a number of times in the past about how it is possible to run PHP scripts from the command line and here dedicate a post to showing how a PHP script can be run by adding a shebang line and running it as if it were any other command.
As part of a series of posts about PHP exception handling, this post looks at how to make regular errors use exception model. Normally only the newer object-oriented extensions throw exceptions but it is possible to make all errors throw an exception instead using set_error_handler.
This post looks at how to extract the first paragraph from an HTML page using PHP's strpos and substr functions to find the location of the first <p> and </p> tags and get the content between them.
This is the third in a series of posts about exception handling in PHP and looks at how to specify a default exception handler. The default handler is called for any exceptions that occur which are not enclosed in a try..catch block.
I've posted previously about how to randomly order a resultset with MySQL using RAND() but the issue with RAND() is it will be inefficient on large tables because each row needs to have the random number calculated before the resultset can be ordered. This post looks at an alternative which requires two queries but will be much more efficient for large tables.
A week ago I looked at how to escape a string for use with a SQL query using the PHP PEAR DB escapeSimple function. This is useful for embedding a variable directly into a SQL query string but it can be a lot easier to use bound placeholders instead and let PEAR DB do all the escaping.
This post is part of a series about PHP exceptions and exception handling; the first post gave a basic overview of how they work and this one shows the information that is available from the exception object when an exception is caught.
When using the PHP PEAR DB database abstraction library it is important to escape variables just as it is when using the native database function calls. If you don't know why this is then do a search using your favourite search engine for "sql injection". This post shows the PEAR DB way of escaping variables.
It is possible to get the value of a PHP constant dynamically using the constant() function. It takes a string value as the parameter and returns the value for the constant if it is defined.
If you are a PHP developer, I'm sure you know the str_replace function for replacing strings and are probably aware that you can pass an array of strings as the search strings and an array as the replacements. What this post looks at is a way of using a single associative array instead of two arrays, which makes dealing with a large number of replacements much more maintainable in your code.
Here's another PHP function I discovered the other day which you may find useful. It's called "range" and is used to create an array containing a range of numbers or letters. This is different from array_fill which creates an array with a number of the same elements and which I covered in my" Intialise an array in PHP with default values" post.
When PHP is installed in Apache files with the .php extension are interpreted as PHP scripts. It is possible to make any file extension be parsed as PHP including .html.
The PHP PEAR Mail Mime library makes it easy to create multi part emails with attachments and alternate plain text and HTML messages. I recently needed to change the character set from the default iso-8859-1 to utf-8 to render some special unicode characters and show in this post how to do this.
Output is not buffered by default with PHP and the contents of the script is sent to the browser in chunks as it is created. PHP's output buffering functions buffer the output giving control over when content is sent, allowing it to be compressed and allowing a mixture of headers and content to be coded without getting those "Cannot modify header information - headers already sent" error messages.
If you need to debug a PHP script but do not have debugging tools at hand in your IDE or similar, an easy way to try to see what's happening and what functions are being called is to use PHP'sbacktracing tools. It can be useful also to include a backtrace when sending or logging errors that have occured on a production website.
This post shows how it is possible to assign multiple variables with the same value with PHP. This can be useful if initializing multiple variables with the same initial value or if needing to make multiple copies of a value and then manipulate each separately.
It's easy to get the filename and directory name components of a full path name with PHP using the dirname(), basename() and pathinfo() functions. The latter also contains the filename extension.
PHP has heredoc syntax like other programming languages to interpolate variables into large string blocks (which I've covered in an earlier post). In PHP 5.3.0 a new string delimiter was introduced called "nowdoc" which works in the same was as heredoc but acts like a single quoted string, so no variable interpolation or parsing is done.
The PHP file_put_contents() function is a useful shortcut for dumping a string into a file (compared with using fopen, fputs etc). By default it will create a new file if it does not exist, or overwrite the file if it does exist. Recently I re-read the documentation for this function and discovered it is also possible to append to a file with file_put_contents.
When scraping content using the PHP Simple HTML DOM Parser it is useful to resolve relative URLs in a page to absolute URLs for downloading additional web pages or images. I do this using the url_to_absolute library byNadeau Software Consulting and show how to do this here, along with a minor fix which needs to be done to their code.
This post shows how to download a web page and find all the link anchor tags in the page using PHP and the Simple HTML DOM Parser which has a jQuery like syntax selector.
Objects in PHP are assigned by reference, so copying an object with the = operator will result in a second variable referencing the same object and not an actual copy. Enter PHP's clone function which creates a shallow copy of the object.
A little while back I posted how to extract the domain, path, etc from a url with PHP and in this follow up post show how to extract the query string into an associative array using the parse_str function.
I've been working at a new job and the interesting thing when working with other people's code is you often learn a heap of stuff you didn't already know. A couple of weeks ago I came across a way to merge arrays in PHP with the + operator, instead of using the array functions (e.g. array_merge) so share this here.
Many websites use Feedburner to serve their RSS feed. The link from the Feedburner feed to the article is a Feedburner URL which then redirects to the original URL. The original URL is still contained in the XML for the feed in the element named <feedburner:origLink> and this can be parsed out using PHP's SimpleXML library, but it's not quite as simple as referring to ->feeburner:origLink because this will not work.
The PHP SimpleXML extension makes it easy to work with XML files by creating an object from the XML structure. To access an element's attributes, use the property() method for that element.
PHP has supported type hinting for parameter functions from version 5.0 for objects and from version 5.1 for arrays. Type hinting means the function specifies what type the parameter must be and if it is not of the correct type an error will occur. Type hinting is not supported for other types, e.g. for strings and integers.
PHP's parse_url function makes it easy to extract the domain, path and other useful bits of information from a full URL. This can be useful for a variety of purposes, such as when spidering content from a website and needing to extract particular pieces of information from the links in the page.
I've been working with the PHP templating engine Smarty at a new job and needed to be able to dump a list of variables that had been assigned to Smarty for debugging purposes. This quick post shows how to dump the variables in your PHP code.
PHP has heredoc syntax similar to other programming and scripting languages which allow multi line strings containing variables to be easily assigned to variables or echoed. This post looks at how to format a heredoc block in PHP and some of the rules.
I recently needed to be able to see what headers the browser sent to the web server with PHP for testing purposes. This is possible using the apache_request_headers() function but it only works if PHP is run on Apache as a module. This post shows usingapache_request_headers() and also an alternative when PHP is run as a CGI. I believe this second method works for lighttpd but have no idea if it works for IIS.
After posting about how to get the meta tags from an HTML web page with PHP was asked how to get the images from an HTML page with PHP like how Facebook does when a link is posted. This post looks at how to get the image URLs from a page using the Simple HTLM DOM Parser library and in a later post I'll look at how to download the images and make thumbnails.
While researching some functions for a PHP article I'm writing I came across the get_meta_tags() function and decided to write a quick post about it.
It's well known that calling count($array) in a for loop in PHP is slower than assigning the count to a variable and using that variable in the for loop instead. However until recently, I wasn't aware that the assignment to a variable can be done in the for loop itself and share this here in this post.
If a resource has been removed from a website, will not be available again and no forwarding address is available then it should return a 410 "Gone" HTTP status. This post explores the 410 status compared with a 404 "Not Found" and 301"Moved Permanently" and shows how to do a 410 with PHP.
PHP's filter_var function can validate if an IP address is valid and can further validate if it is an IPv4 IP, IPv6 IP, or not within the private or reserved ranges. This post shows some examples using filter_var.
This post shows how to get the number of days in a month with PHP by specifying the year and month. This can be useful when generating a calendar application without having to manually code in the number of days each month has, and not having to worry about the number of days in February which varies on leap years.
PHP's CURL functions make it easy to download content from websites. Sometimes you need to be able to manage cookies set from the site the data is coming from. This is done using the CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE options as shown in this post.
I recently posted how to do geo targeting with PHP with the GeoIP functions but discovered when testing something today that PHP throws an E_NOTICE notice error if the IP address does not exist in the database.
The PHP CURL functions use the libcurl library to allow you to connect to various servers and different protocols. If the http referer string is not explicitly defined then nothing will be sent to the web server, but there may be times when you need to pass this along with your request.
The PHP GeoIP library makes it easy to look up country codes and names from an IP address. It's not enabled/installed by default so you need to install it before you can access these functions. I've already posted about how to do this with Debian and other Linux distros will be similar.
The PHP CURL functions use the libcurl library to allow you to connect to various servers and different protocols. If the user agent string is not explicitly defined then nothing will be sent to the web server. If you are scraping a website with CURL for whatever reason, there may be times you need to specify the useragent string and this post shows how to do it.
A PHP install on Debian 5 by default does not include the Xslt extension which means the following error will occur if trying to use the XsltProcessor class: " Fatal error: Class 'XsltProcessor' not found...". This post shows how to install the extension on Debian 5.
The PHP CURL functions use the libcurl library to allow you to connect to various servers and different protocols. This post shows how to make an HTTP POST with PHP and CURL passing several form fields. This can be useful for testing your own web forms, connecting to APIs that require POST data and so on.
PHP's error_reporting() function allows a script to check what the current error reporting level is and/or modify it. I wouldn't normally recommend changing the error reporting level programatically, but there may be times when it's needed. The nice thing is it's easily possible to get the current level, change it, and then set it back to what it was previously.
PHP has the serialize and unserialize functions for converting data into a storable value (for example being able to store an array in a database field). An issue with the unserialize function is that it will issue an E_NOTICE error if the data is notunserializeable. This post looks at how to prevent the notices from being displayed if you have error reporting at a level that will show notices.
There are a number of ways to find the files in a directory with PHP. I've covered
The Google Analytics API has a filters feature which allows you to filter the data in a variety of ways, including filtering by URL. This means that you can get specific metrics (e.g. pageviews etc) for a single page from the GA API.
My last PHP post looked at how to do email validation with filter_var() which is available from PHP 5.2.0. However if the server your website is being hosted on has an earlier version of PHP then you can't use filter_var(). This post looks at how to use the Zend Framework to validate email addresses instead, if you are using the Zend Framework.
There's no longer any need in PHP to create your own regular expressions to try to validate an email address; simply use filter_var() instead. This is available from PHP 5.2.0.
A couple of weeks ago I posted how to read through a directory with PHP using the opendir() readdir() and closedir() functions and now look at the glob() function. glob() returns the filenames into an array and supports pattern matching so it can be very easy to find e.g. jpg images in a particular directory.
Last week I looked at how send a username and password with PHP CURL. Using CURL is useful because you can examine the return information to see if the request was successful etc, but if your hosting provider doesn't have CURL for PHP enabled then you can still attempt to get the file by using file_get_contents and passing the authentication as part of the $context parameter.
CURL and PHP combined can be really useful for getting data from websites, connecting to APIs (such as the Google Analytics API) and so on. Sometimes you may need to connect to a website that is password protected so this post looks at how to pass the username and password with PHP and CURL.
PHP's opendir() readdir() and closedir() are used for reading the contents of a directory (there's also glob() and scandir() but I'll cover those in later posts). Combined with functions like is_file() is_dir() and is_link() and you can easily build up a directory tree or process files etc.
PHP's get_included_files() function returns an array containing a list of included files by your script, including the script itself. This post looks at the filenames returned in the array and corrects a couple of errors in the PHP documentation.
This is a summary post with links through to all the posts on my blog where I've looked at various functions using PHP's IMAP functions to download mail and extract attachments etc.
The Google Analytics API allows filtering to be done on the result data before it is fetched so you could, for example, only get data for visitors from the United States. This post shows how to format the filters field in PHP and also how to use my Google Analytics API PHP Class with filters.
The following shows example usage to get the most popular pages from Google Analytics using my PHP class for the GA API.
I've previously looked at how to set PHP configuration options in an Apache .htaccess file which allows you to change PHP_INI_PERDIR or PHP_INI_ALL settings but notPHP_INI_SYSTEM. All three of these settings types can be modified in an Apache virtualhost's settings.
PHP has a large number of configuration options which can be set in the php.ini file, Apache virtualhost settings, .htaccess and with the ini_set function. This post looks at the ini_get_all function which returns an array containing all the possible configuration options, what their global and local script value are and where they can be modified.
PHP errors are by default logged to the web server's error log file (at least they are with the default setup on most Linux distros) but it is also possible to instead log PHP errors to a file of your choice. This is useful on production websites so you can periodically check for errors and fix them in a location other than the default webserver error log file.
It is possible with PHP to automatically append or prepend a file to a script using the auto_append_file and auto_prepend_file configuration options. These options can be set in the PHP config, virtualhost settings or in a .htaccess file. This post shows how to set these and how to override a setting so no file is appended or prepended.
The Google Analytics API is a powerful tool for accessing analytics data without having to log into the web interface and means you can easily have automated processes for collating data and saving it to a database, emailing information on a daily basis etc.
I have created a PHP class for accessing the Google Analytics API with CURL and using DOMDocument to parse the XML. The resulting class and example script can be downloaded here and there are a number of posts on this website showing how to use it.
Just quickly following up my post from earlier on today where I looked at how to log into the Google Analytics API using PHP and CURL using Username/Password Authentication I wrapped the login code up into a class with methods for logging in and then calling API functions.
Google have finally made an API available for Google Analytics although it's currently in beta and the specs are subject to change. I've been playing around this morning logging in usingClientLogin Username/Password Authentication with PHP and CURL and show how to do this here. In future posts I'll look at how to actually use the API but this will get us all started for now.
I've been coding PHP since 1999 and I'm still discovering functions I didn't know about. Just the other day I read someone's post about some useful PHP functions and I knew all of them except for the getdate() function so I thought I'd cover it here.
If you call the curl_init function in PHP and do not have the curl module installed you will get the error message "Fatal error: Call to undefined function curl_init() in /path/to/script.php on line XY". This post shows how to install the PHP curl module on Debian Linux and the instructions should also work on all Debian derived distros such as the Ubuntu family.
PHP has a large number of configuration option which can be set in the php.ini file, Apache <virtualhost> blocks, .htaccess files and ini_set(). This post looks at how to set PHP configuration options with Apache's .htaccess files.
In the past I've written about how to save data as a CSV file using PHP, MySQL queries and mysqldump and in this post show how to send the results of this data to a web browser setting the headers correctly with PHP so the browser gives you a "save as" dialog instead of displaying it on the page. The headers also include the filename which is supplied as the default in the save as dialog.
There are a couple of ways to export data from MySQL to a CSV file (refer to my using mysqldump to save data to CSV files and export data to CSV from MySQL posts for details) but neither of them supports adding a header row to the CSV which contains the column names. This post looks at how to export the data from MySQL into a CSV file with PHP including a header row.
If you call the ImageCreateFromPNG function (and similar image processing functions) in PHP and do not have the GD module installed you will get the error message "Fatal error: Call to undefined function ImageCreateFromPNG()" error message. This post shows how to install the PHP GD module on Debian Linux and the instructions should also work on all Debian derived distros such as the Ubuntu family.
This post shows how to use the MySQL "SHOW TABLES FROM" SQL query to get a list of tables using PHP. This list could either be stored to an array or echoed out to web browser, command line etc.
On Thursday I looked at how to get a domain name's IP address with PHP using the gethostbyname() function. However some domains resolve to multiple IP addresses so this followup post looks at how to get a list of IP addresses for a domain in PHP using the gethostbynamel() function.
It's easy to get the IP address for a domain name using PHP's gethostbyname() and gethostbynamel() functions. This post looks at some examples of using thegethostbyname() function in PHP to get a single IP address for a hostname.
Having reached the conclusion of my series on getting Google Analytics data by email I had an enquiry from someone asking how to find only the unread email messages using PHP IMAP. This is simple enough to do and can be done either when looping through the messages or using the imap_search function.
My last PHP post looked at how to delete email messages using PHP's IMAP functions. This is straight forward on a regular POP3 or IMAP mail server but deleting a message when connected to Gmail just removes it from the inbox and it's still available in "All Mail" rather than being moved into the trash. This post looks at how to move an email into Gmail's trash with PHP IMAP.
I've been writing a series about sending Google Analytics data by email and then processing the emails with PHP's IMAP functions. Once the email has been processed you'll probably want to delete the emails from the mailbox afterwards so this email looks at how to delete emails using PHP's IMAP functions.
This post shows how to extract data from an email attachment from data sent by Google Analytics with PHP. I've covered how to download and extract attachments with PHP's IMAP functions in previous posts and am now coming to the end of this series finally showing how to get the data out of the attachments.
While writing my series on extracting data from Google Analytics emails with PHP I discovered PHP has a new function called str_getcsv which works the same way as fgetcsv but extracts CSV data from a string instead of from a file.
If you are getting the "Fatal error: Call to undefined function imap_open()" error in PHP when using the IMAP functions then they are not installed with your installation of PHP. This post looks at how to install the PHP IMAP functions on Debian and should also work for Ubuntu/Kubuntu/etc and other Debian derived Linux distros.
This is a supplementary post in my series about having Google Analytics data sent by email and then downloading and parsing the data with PHP. This post simply contains a PHP function for extracting all the attachments of an email using the PHP IMAP functions into an array.
At the start of 2009 I added a "Recent Posts" section to the sidebar navigation of this blog and decided I'd update it using data from Google Analytics. Unfortunately Analytics doesn't have an API to get data but does have a function for sending data by email on regular basis either as a TSV, CSV, XML or PDF attachment.
Therefore a somewhat spordaic series of posts began appearing on this blog showing how to get Google Analytics data by email and use PHP's IMAP functions to read through a mailbox and extract data from the attachments.
This post is part of a series about downloading email using the PHP IMAP functions. The ultimate goal of the series is to show how to export Google Analytics data by email, and then use PHP to connect to the mail server, find and download the appropriate message and then load the data into a database. This post looks at how to look for a specific email message using the PHP IMAP functions.
This post is part of an on-going series on this blog about connecting to IMAP mailboxes with PHP, ultimately showing how to download and parse reports from Google Analytics. When logging into an IMAP server with PHP the default mailbox is used - usually the INBOX. This post looks at how to list the mailboxes for the IMAP account and then how to connect to one of the other mailboxes.
A couple of weeks back I posted how to use the PHP IMAP functions to download email from an IMAP server. This post looks at how to do the same but downloading IMAP mail from Gmail, which you need to connect to on a different port and use SSL. Earlier today I posted how to enable IMAP mail access in Gmail so you'll need to ensure that's done first.
You can define constants in PHP with the define() function and can check if a constant has already been defined with the defined() function. This post looks at both functions with some examples.
Yesterday I looked at how to copy a table with MySQL using some SQL queries. This post looks at how to automate the process with a PHP script saving you having to type in and adjust queries each time you want to back up a table.
This post is part of an ongoing series which aims to show how to extract data from Google Analytics using its scheduled email reports system. I have already looked at how to send Google Analytics data by email, and how to use the PHP IMAP functions to download email. I will also look at using other PHP libraries to download email and attachments, but for now this post looks at how to extract email attachmentsusing the PHP IMAP functions.
I recently made some minor layout changes to my blog including the positioning of the advertising from the top of each article to after the first paragraph. In this post I share the PHP code used to add some additional HTML code after the first closing </p> tag in a page's content.
This post looks at how to connect to a POP or IMAP mailbox using PHP's IMAP mail functions and retrive the number of messages in the mailbox, the message headers and body, and then to delete the message.
If you are getting the "Fatal error: Call to undefined function imap_open()" error in PHP when using the IMAP functions then they are not installed with your installation of PHP. This post looks at how to install the PHP IMAP functions on CentOS and should also work for Red Hat Enterprise Linux (RHEL), Fedora and other derived Linux distros.
As well as running PHP scripts via a web server such as Apache, you can also run PHP scripts from the command line (it's also possible to write GUI apps with PHP using PHP-GTK, but I'll maybe look at that another time). This post looks at the two ways you can run a PHP script from a *nix based computer (Linux, Unix, BSD, OSX) and the single way you can do it from Windows.
Sometimes you may need to get the first sentence from a block of content for use as e.g. the meta description for a page. This post looks at how to get the first sentence using PHP.
The PHP function is_callable() tests to see if a function or class method can be called, and solves an issue with the method_exists() function which will return true for all methods regardless of whether or not they can actually be called.
The Zend Framework has a component called the Zend_Registry which allows you to store data into a sort of global space which lasts the duration of the script. Once saved to the registry the data is available throughout the application. This post shows how to save some data to the registry and then retrieve it.
Last week I looked at how to see if a function exists in PHP and this time will look at how to check if a class method exists in PHP.
Some of the upcoming jQuery posts I will be publishing will be making AJAX requests so I thought it fitting to post how to tell if the incoming request is an AJAX request in PHP for the PHP programmers out there. This is useful if your script handles both AJAX and non-AJAX requests and you need to know which sort it is.
Since PHP 5.1.0 it has been possible to change the default timezone that PHP uses using the date.timezone configuration, which can be set for the entire server in php.ini or httpd.conf, on a virtualhost by virtualhost basis, or using the ini_set() function. This post looks at how to change the timezone in PHP using the ini_set function.
Just a quick little post to remind that PHP/Apache sets the content-type header by default to text/html. If you are serving other content, such as an RSS feed, you need to remember to change the content type to the appropriate format.
Although you can set content type in the HTML <head> section of a web page the web server can also send the content type as one of its headers, and it can cause unexpected consequences when rendering a page in a browser. This post looks at how to set the content encoding type header with PHP.
PHP has the class_exists() function to check if a class has already been defined. You may need to take action depending if a class exists or not, and need to watch out for "gotchas" when also using __autoload().
Having used the Zend Framework on a couple of projects and spent a lot of time reading the documentation I discovered the use of method chaining. This post looks at how to use method chaining in PHP.
Last week David Walsh posted about validating numeric values and digits with PHP on his excellent blog. I posted my own comments about his particular post but they never appeared so I decided to post a better response here.
Sometimes you need to be able to get the class name or parent class name of an object in PHP to do something conditionally etc. This post looks at how to do this.
PHP introduced the __autoload() function in version 5 which is called whenever the code tries to use a class that has not yet been defined. You simply put some code into __autoload() to include the appropriate class file and don't have to bother about manually including those files. This post looks at how to do this with examples.
PHP has a number of hashing algorithms available for creating hash values of files and strings. A hash is a non-reversible fixed length string which has a number of applications, such as storing a password in a database in a way that can not be read. This post looks at how to show the available hashes in PHP and how to use the hash() function to generate a hash value.
While working with some image functions in PHP I changed the output image from JPEG to PNG (from the ImageJPEG to ImagePNG functions) and got the error message "gd-png: fatal libpng error: zlib error". This post looks at the cause of the error and the solution.
If you have long running batch processes with PHP that are run by cron and you want to ensure there's only ever one running copy of the script, you can use the functions getmypid() and posix_kill() to check to see if you already have a copy of the process running. This post has a PHP class for checking if the script is already running.
While testing a web service I was creating in PHP using the PHP SoapClient and SoapServer classes I got the error "Unable to parse URL" from a WSDL file generated using Zend Studio. This post looks at the error and how to fix it.
A few days ago I posted how to hide the information schema in phpMyAdmin and of course using the advice in that post you can hide any database you want. The hide_db phpMyAdmin configuration option is a regular expression so you can use it to hide several databases, and this post looks at how to do this.
When you log into phpMyAdmin you can only see the databases for which you have access rights, as well as the information_schema database. It is possible to hide this database if you want to. This post looks at how to hide the information_schema database in phpMyAdmin.
PHP has a useful function for initialising an array with default values called array_fill(). This post looks at how to use the array_fill function and the output of these arrays with the print_r function.
Most of PHP's file functions can be used to open local files as well as remote files via HTTP etc. By default the user agent string passed when making an HTTP requestis an empty string but it is possible in PHP to change the user agent string to something else. This post looks at how to do this.
print_r is a useful PHP function for displaying the values of an array or object when debugging etc. Having been a PHP programmer since the days of PHP 3.x I didn't realise this function had added the capability to return the information as well as print it from PHP 4.3.0 and only discovered this in the last few days. This post gives a brief overview of PHP's print_r function.
Sometimes you might need to know if a number is odd or even, and this post looks at how to determine if a number is odd or even in PHP using the modulus arithmetic operator.
phpMyAdmin is a web based front end to MySQL written in PHP. It likes to have the mbstring extension loaded if using a multi byte character set and will display warnings when you first log into phpMyAdmin if it is not available. This post looks at the error message and how to install the mbstring extension for PHP on CentOS / Red Hat Enterprise Linux using yum.
It is important to keep software up to date on your computer and web servers. I manage a few webservers which run Apache/PHP/MySQL on CentOS, a Red Hat Enterprise Linux derivitive, and use YUM to install software and keep it up to date. This post looks how you would just do an update to PHP using YUM on CentOS.
In previous posts I looked at how to optimize a MySQL table from the MySQL command line interface and from phpMyAdmin by using the optimize [tablename] command to free up unused space. In this post I will look at how to do this with a PHP script which could be run periodically to optimise all non-optimal MySQL tables.
I've been doing a reasonable amount of PHP CLI (command line interface) programming recently for getting stuff from log files and converting large numbers of images. Some of these processes can some quite a while to run, sometimes as long as several hours, so it can be useful to know roughly how far through the process it is.This post looks at how to output a counter to the command line from PHP which replaces itself on each iteration.
The Zend Framework is a PHP framework with many individual components that do not require you to use the whole framework. In this post I will look at how to send an emailusing the Zend Framework's Zend_Mail component.
FCKeditor is an in-browser WYSIWYG HTML editor and I use it on a number of websites including in the blog admin for this website. This post looks at how to put FCKeditor into a web page using PHP. In future posts I will look at some of the other functions and features of FCKeditor.
When writing my "Get a list of all available constants with PHP" post I discovered there are a number of usful date format constants in PHP which can be used with the date() function. (Refer to my "Formatting Dates with PHP" post for more details about the PHP date function). This post looks at these constants and how to use them with the date function. Please note that these constants have only been present in PHP since 5.1.1.
PHP is a loosely typed language and assigns types to variables depending what is assigned to it. Variables coming from get/post and cookies etc are generally cast as strings rather than other types and there are often other times when you need to specifically cast a type in PHP as e.g. an integer. This post looks at how to type cast in PHP and some of the results than can come about from type casting.
When you submit a form using a web browser the script processing the form often redirects after it has done its work to a thank you page (or similar). The response type people usually use when coding with PHP is a 302 redirect because it's the default used when issuing a Location: header. The problem with this is on a page refresh the browser is likely to submit the form again. Instead you can use a 303 redirect to prevent the form being submitted again. This post looks at what a 303 response code / redirect is and how to send one with PHP.
If you ever need to send an image file with PHP from the web server to the web browser you need to add an additional header using the header() function so the browser knows it's an image and not regular HTML. This post looks at the headers you need to use.
PHP has the function get_defined_constants() which allows you to get a list of all the available constants in an array. This post looks at how to use the get_defined_constants() function and example output from it.
PHP has the function get_declared_classes() which allows you to get a list of all the available system and user defined classes in an array. This post looks at how to use the get_declared_classes() function, the output from it and how to sort the list into alphabetical order.
PHP has a function called getimagesize() for getting the width and height from an image. I'm always forgetting the name of the getimagesize() function so I decided to write a post about it and showing some examples and that way maybe I'll remember in the future...
PHP has the function get_defined_functions() which allows you to get a list of all the available system and user defined functions in an array. This post looks at how to use the get_defined_functions() function,the output from it and how to sort the list into alphabetical order.
The PHP command line interface or CLI allows you to run PHP scripts from the command line. It also has a number of flags that can be passed to it which allow you to see which modules are available, do a syntax check on a file, view PHP information etc. This post gives a basic list of the command line arguments available for the PHP CLI and in later posts I will look at some of the options in more detail.
PHP has the getopt() function for getting options or command line arguments from a CLI PHP script. This provides a simple way to get values from the command line like e.g. "-a foo". This post looks at how to do this. More details can be found in the PHP getopt() manual page.
Yesterday I posted how to check if a MySQL table exists using show tables or the MySQL information schema. Today I am posting a simple PHP function I created which you can use to test if a table exists.
Help! There are errors in my PHP code and there are no error messages being displayed. I've even set error_reporting to E_ALL and still PHP is not displaying the errors. How do I debug it? How do I show the errors? This post looks at the very simple answer to these questions.
phpMyAdmin is a web based administrative tool for the MySQL database server. After logging in to phpMyAdmin there's a drop down box to select the font size as a percentage which always defaults to 100% and is too big for my liking. After changing the value, the font size is remembered as a cookie so the next time you log in the font size chosen is remembered. However the font size cookie drops off eventually and when logging into a phpMyAdmin that I haven't logged into for a while I find it annoying having to change the font size each time. This post looks at how to change the default phpMyAdmin font size.
PHP contains a useful date function which can be used to determine if the current year or a specific year is a leap year. This post looks at how to use the date function to do this.
When a web browser moves from one website to another and between pages of a website, it can optionally pass the URL it came from. This is called the HTTP_REFERER, and this post looks at how to use this variable with PHP.
The first MVC framework I used was Code Igniter but I've decided to give the Zend Framwork a go because I like their approach to use what you need, and after some studying of the controllers and view functionality those parts do more or less exactly what I want. There are ways to add additional routes to the controllers but I couldn't work out initially how to inject them into the controller from the Zend Framwork documentation. This post shows the original example from the Zend Framework documentation and then a more full example which I constructed using other sources.
phpMyAdmin by default opens a popup window when you click the "Edit" link underneath a query. I personally prefer to not have a popup window open and this post looks at how to change the default behaviour.
The end of daylight savings in New Zealand has been changed from Sunday March 16th (today) to Sunday April 6th. Last week I looked out how to check the daylight savings dates will be applied correctly on Linux, but now that it's actually the day itself it turns out that while the operating system is using the correct date, PHP is not due to PHP5 maintainin its own internal timezone database. This post looks at how to temporarily correct the solution until it's fixed in the distro's PHP builds.
When you change the URL/URI of a page, a permanent redirection should be set up from the old address to the new address to let user-agents know where it can now be found. When using a web browser the redirection is usually seamless; for search engine bots they will now know to stop requesting the old page and instead request the new address in the future. This post looks at how to do this with PHP.
PHP can be run as a webserver module, as a CGI application or from the command line as a CLI script. There is both a function and a PHP constant which allows you to determine whether PHP is being run via HTTP or CLI. This post looks at the function and constant and the possible values, as determined in the PHP 5.2.5 source code.
The PHP function tempnam() creates a file with a unique name. This can be useful if you need to output some data into a temporary file for one reason or another, and the actual name of the file is not important.
If you get the following error message in PHP then it means you need to have the XSL extension installed. Obviously the /path/to/file.php will be the actual path and filename of the PHP script the error occured in, and the line number will be the actual line. The PHP manual says that "PHP 5 includes the XSL extension by default" but one of my CentOS 5 installations it didn't seem to be; the following post looks at how to install this extension on CentOS 5.
Fatal error: Class 'XsltProcessor' not found in /path/to/file.php on line 138
APC is the Alternative PHP Cache, which is a free, open, and robust framework for caching and optimizing PHP intermediate code. I posted about how to install APC on Linux a couple of days ago, and will now look at the apc.php script which comes with APC and shows information about how much of the cache is being used, what files are being cached, the number of times they've been accessed etc.
APC is the Alternative PHP Cache, which is a free, open, and robust framework for caching and optimizing PHP intermediate code. What this means is that APC reads your PHP files, parses them into a more efficient binary format and then caches them in memory so that each request for your PHP files and PHP library files can be fed from the parsed cache. This will generally lead to a speed increase when serving a PHP site, especially one with a lot of library files. This post looks at how to install APC for PHP on Linux. The Linux distribution I used was CentOS 5, but it should be fairly similar for most distros.
If you get the following error message in PHP then it means you need to have the PHP GD extension installed. Obviously the /path/to/file.php will be the actual path and filename of the PHP script the error occured in, and the line number will be the actual line.
Fatal error: Call to undefined function ImageCreateFromPNG() in /path/to/file.php on line 379
You'll also get this error message using other functions such as ImageCreateFromJPEG() if the PHP GD library is not installed.
A little while back I needed to split a large Apache log file (3.5GB) up into smaller pieces and wanted to break it up into several files, with one for each day of the month. I initially tried using "grep" on the command line but this proved to be too slow, and I needed to run it once for each day and month so it was going to take 92 times to run, extracting just one day at a time over the course of three months. I ended up writing a quick little PHP script which was able to split the 3.5GB file into 92 files, one for each day of each month in under 4 minutes.
The PHP function array_unique() allows you to create a new array which contains only the unique values from the original array. This post looks at some examples of using the array_unique function.
The strtotime() function in PHP allows you to convert English text date time strings into UNIX timestamps. It is useful for converting database datetime strings into UNIX timestamps and also creating dates into the future or past based on the current time or relative to a date and time in the future or the past. This post looks at some examples of doing this.
PHP has a really useful date() function for formatting dates from timestamps. When used in conjunction with strtotime() you can do some really quick and easy manipulation and formatting of dates.
It is possible to trigger an error in PHP. This can be useful for debugging purposes, or if there is some condition which occurs in your PHP script which requires a PHP notice, warning or full error which causes the script to halt execution, and which would not be generated by PHP itself.
I run a number of web servers with PHP and MySQL and have a PHP command line script that runs on a daily basis to back up MySQL databases using the mysqldump command. It would be possible to do this using a simple bash script as well, and I know I used to use a bash script in the past but for some reason switched it to PHP at some stage.
There are several PHP "magic constants" (or "magical contants") which can be useful for a variety of reasons. These magic constants aren't actually constants at all, but effectively behave like them, although the values change depending on the context.
I've finally set up an RSS feed for this site and one of the things I needed to sort out was the use of URLs and image tags. All the anchor tags in this site are relative, and so are all the image sources. This isn't going to work in an RSS feed because it would mean none of the links would work, and the images would all be broken. Fortunately this is easy to fix with the use of PHP's string replacement functions.
I have been in the process of moving my websites from a dedicated machine running Gentoo Linux to a VPS (Virtual Private Server) running CentOS 5. One of the ecommerce websites uses an old install of osCommerce which expects register globals and register_long_arrays on, otherwise things won't work very well.
While testing the site out on the new server, I couldn't work out why some of the form posts were working and some weren't. For example, on some pages I could add items to the shopping cart but on others I couldn't. I also couldn't click the form button to proceed to th checkout or update my basket: whenever I tried it kept showing me the same basket page again.
Unfortunately there is no pre-built module/extension for MSSQL for PHP in the Yum repositories for CentOS 5, so you need to build it yourself. It's a reasonably simple process, but you do need to have gcc and php-devel packages already installed (and a whole bunch of others which I'll list at the end of this post).
I've often found that something gets left out or forgotten when moving a website from an old server to a new install. I've just finished migrating one of my customer's sites to a new CentOS 5.0 install with Apache 2.2 and PHP 5.1.6, and there's one single PHP script in the site which uses the SoapClient class.
Naturally I'd forgotten to test this particular function until after the migration was complete, and was wondering why the script had failed. A quick look in the Apache error log file revealed the following error message: PHP Fatal error: "Class 'SoapClient' not found"
"echo" and "print" are used in PHP for writing strings out to a stream. I have always used concatenation when writing out multiple strings with echo or print, but recently discovered that echo accepts multiple arguments or parameters, comma separated like a regular function call. This post does some benchmarking to see which is faster: echo with commas, echo with concatenation, or print with concatenation.
This article covers howto fork a child process using the PHP command line client and PHP process control functions. Several examples illustrate how to create child processes and make the parent wait until they have finished before continuing processing.
phpMyAdmin is a tool written in PHP intended to handle the administration of MySQL using a web browser and is one of the most active projects on Sourceforge.