Category Archives: php

Check whether a number is a Fibonacci number in PHP

Creating an algorithm to find all of fibonacci numbers between 0 and $x is a simple exercise in recursion, but how do we find out whether a given number is a fibonacci number?

The wikipedia entry gives us the algorithm, but how can we implement it in PHP? Below is a simple, fast code snippet that takes a number as input and returns true if the number is a fibonacci number, and false otherwise:

function isFibonacci($number) {
    $test_1 = sqrt(5 * pow($number, 2) + 4);
    $test_2 = sqrt(5 * pow($number, 2) - 4);

    return ctype_digit((string)$test_1) || ctype_digit((string)$test_2);

isFibonacci(25);   //false
isFibonacci(1597); //true

If this helped you, leave a message in the comments below! See you all next time!

A fix for direct @username tweets with image attachments using tmhOauth

Direct link to code download:

Being one of the first reliable OAuth libraries for Twitter to support image attachments to tweets has also made thmOauth one of the most popular.

That being said, there is an ongoing issue with the tmhOauth library that has popped up for me from time to time, which other users have also encountered, and although it isn’t a deal-breaking bug, diagnosing the problem is usually a bit of a head-scratcher, and left unresolved, it can be quite annoying for your app’s users.

The issue arises when you use tmhOauth to try to tweet or reply directly to an @username with a tweet that contains also contains an image attachment.

The following code comes straight out of the tmhOauth’s image upload example, and it works perfectly:

$code = $tmhOAuth->request(
    'media[]'  => "@mypic.jpg;type=image/jpeg;filename=mypic.jpg",
    'status'   => 'Picture time',
  true, // use auth
  true  // multipart

However, changing the status field in the array as follows will break the library and the tweet will fail:

$code = $tmhOAuth->request(
    'media[]'  => "@mypic.jpg;type=image/jpeg;filename=mypic.jpg",
    'status'   => '@themattharris is it still picture time?',
  true, // use auth
  true  // multipart

The problem is caused by the way PHP’s libCurl interprets the “@” symbol at the beginning of a POST field’s value in a multipart form.  When a field’s value is prefixed with “@”, libCurl assumes the field is referencing a file whose contents should be posted, rather than the actual supplied contents of the field.  This is as much a libCurl bug as it is a tmhOauth bug, but it is far easier to patch tmhOauth, so that is what we’re going to do.

The first thing we’ll need to learn is what a posted form looks like, so we can build our form headers manually, rather than allowing PHP/Curl to interpret the values itself.    According to the W3C, a typical form submission might look something like this:

   Content-Type: multipart/form-data; boundary=AaB03x
   Content-Length: 23423423

   Content-Disposition: form-data; name="status"

   Picture time!
   Content-Disposition: form-data; name="media[]"; filename="mypic.jpg"
   Content-Type: image/jpeg

   ... contents of mypic.jpg ...

Let’s assume that the boundary=AaB03x in the above example is a randomly generated string, and could potentially be anything. It’s used as a form field delimiter by the user agent (ie – your browser) to build the form data to submit, so that the receiving server can understand where one field ends and another begins. So, the first thing we need to add to tmhOauth is a randomly generated delimiter that we can use throughout the library to denote the beginning and ending of our form and field data. Add the variable to the tmhOauth class declaration:

class tmhOAuth {
  const VERSION = '0.7.0';

  var $response = array();

  var $delim = "";

Notice that we are initializing the variable with an empty string. In the class constructor we will add code to randomly generate the form delimiter using PHP’s uniqid() function:

$this->delim = "-------------------" . uniqid();

Now we’re ready to start building some multipart form data!  The first thing we should add are some functions to return the form fields in the format we want. Let’s add some functions to handle text fields and image attachments first:

  private function mediaField($key,$file,$filename,$type) {
      $field = "--" . $this->delim . "\r\n";
      $field .= 'Content-Disposition: form-data; name="' . $key . '"; filename="'.$filename.'"' . "\r\n";
      $field .= 'Content-Type: ' . $type . "\r\n";
      $field .= "\r\n";
      $field .= file_get_contents($file) . "\r\n";

      return $field;

  private function textField($key,$param) {
    $field = "--" . $this->delim . "\r\n";
    $field .= 'Content-Disposition: form-data; name="' . $key . '"';
    $field .= "\r\n\r\n";
    $field .= $param . "\r\n";

    return $field;

These functions simply generate a text block to define a POST field for the form. The mediaField() function generates a POST field for a file attachment by specifying a filename and content-type, and including the file’s actual contents, while the textField() function generates a simple text field. Next, we’ll define a function that uses these two functions to build the full form data for the tweet with media:

  private function buildPostFields() {

      $formData = "";

      foreach ($this->request_params as $key => $param) {

          if (substr($param,0,1) == "@") {
              @list($file,$type,$filename) = $this->getMediaAttribs($param);
              if(!empty($file) && file_exists($file)) {
                  $formData .= $this->mediaField($key,$file,$filename,$type);
              } else { // It's not a file - it's a twitter username!
                  $formData .= $this->textField($key,$param); // just a plain text field
          } else {
              $formData .= $this->textField($key,$param); // just a plain text field

      $formData .= "--" . $this->delim . "--\r\n\r\n"; // final post header delimiter

      return $formData;

The difference between the form data built by the buildPostFields() function and libCurl is that this function checks to make sure that the file exists before trying to insert its contents into the form. If the file does not exist, that is a good indicator that the “@” at the beginning of the string refers to a Twitter username rather than a file to attach to the tweet, so we need to treat is as plain text. There is just one more function that we need to define, and that is the getMediaAttribs() function called above. This function simply checks the content type of the image attachment and ensures that all of the required file data is available before we try to tweet the picture:

  private function getMediaAttribs($param) {

      // if there are already semicolons in the string, the user has specified all of the required fields in the request.
      // No need to continue...
      if (strpos($param,";")) {
          // strip the "@", we're not gonna need it where we're going
          if (substr($param,0,1) == "@") $param = substr($param,1,strlen($param));
          return explode(";",$param);

      $file = substr($param,1,strlen($param));

      // if the file doesn't exist, there's not much we can do about it, so just forget it - the twitter post is going to fail anyway
      if (!file_exists($file))
           return array(null,null,null);

      // we're going to have to get the mime type manually
      // we'll also have to set $filename to be the same as the last part of the $file string

      $fileinfo = getimagesize($file);
      $filetype = $fileinfo['mime'];

      $filename = substr($file,strrpos($file,DIRECTORY_SEPARATOR),strlen($file));

      return array($file,$filetype,$filename);

And that’s it! All that’s left is integrating this code into the tmhOauth project, and you can see how that’s done by checking out the code here:

I hope this fix will help someone out there avoid the headache of trying to figure out why their tweets won’t work. If you have any questions about using this fix, please feel free to contact me or reply to this post.

See you next time!

Before I get started… (aka – Always Sanitize Your User Input!)

I’ve read through a lot of PHP sample code over the past decade, and one thing that is almost universally missing from the samples is data sanitization.  Many experienced developers assume that data sanitization is understood to be a requirement, and so they (correctly) exclude it from their demo code in order to save time and for the purposes of clarity.  In most of my examples on this blog, data sanitization will also be absent.  However, I think that this attitude has helped foster a culture of nonchalance in the PHP community when it comes to verifying input data and has led to some major disasters that could have easily been avoided with a little experience, attention to detail, and of course, a dash of proper QA.

With that being said, many modern PHP frameworks take care of the heavy lifting for you when it comes to data sanitization.  In CodeIgniter, the Input Class offers automatic data sanitization, XSS filtering and some other assorted security features and helpers.

For anyone who is not using a framework (and those who are, but want to understand PHP’s internal input filtering capabilities), it is important to know about the data sanitization functionality available in PHP, especially the new data filtering available in PHP 5, which has seriously improved the security of the system as a whole.  As far as I’m concerned, the two main priniciples behind data sanitization are:

  1. Ensure that the data you receive is in the expected format. Make sure integers are integers, and email addresses are email addresses, etc.
  2. Ensure that dangerous or malicious data is properly formatted or escaped to avoid damage to your website, to prevent theft or fraud, and to ensure the security and privacy of your users.

Big job, right? Luckily, PHP 5 has some really nice built-in features that help us accomplish this quite effectively. The most basic filtering function is filter_var. This function is extremely easy to use, and as the name suggests, filters variables to conform to the expected type.  As an example, if you want to ensure that a variable passed to a function is an integer, you would check it using the following filter:

function findUserById($id) {
    $id = filter_var($id,FILTER_VALIDATE_INT);

The code above will not only validate that the variable $id is, in fact, an integer, but it will also set $id to 0 (or false) on failure. It is helpful to be familiar with the various validation and sanitization filters that PHP 5 has available.

The filter_var function also allows various flags to be set to help PHP to filter the data to your satisfaction. For example, the following code will ensure that your variable is an integer, but it will also set a default value of 3 that will be returned on failure, and allow for hex values in addition to decimal values:

function setCode($id) {
    // let's assume that $id = 0XFC75;
    $options = array(
        'options' => array(
            'default' => 3
        'flags' => FILTER_FLAG_ALLOW_HEX,
    $id = filter_var($id, FILTER_VALIDATE_INT, $options);

To save you the trouble of copying all of your $_POST and $_GET variables into local variables and then filtering them, PHP also offers input filtering via the filter_input function. This function is basically the same as filter_var, with minor differences in syntax that allow you to specify where to look for the variable you want to filter. For example, say you had a variable in your $_POST array called “firstname” that you would normally access using $_POST[“firstname”]. Here is how you could filter it to ensure that potentially dangerous characters like single and double quotes are escaped properly:

// Assume the user has entered his first name into a field called "firstname" and submitted the form
// you would normally access it using the $_POST["firstname"] variable

$firstname = filter_input(INPUT_POST,'firstname',FILTER_SANITIZE_STRING);

Now you can access the sanitized value using the $firstname variable!

The same is true of variables being passed in from the URL:

// Imagine the URL is 

$firstname = filter_input(INPUT_GET,'firstname',FILTER_SANITIZE_STRING);

And again, the sanitized value from $_GET[“firstname”] is now stored in the variable called $firstname.

Finally, PHP offers an even more streamlined approach to sanitizing your input data, using the filter_input_array function. This function allows you to define how PHP should sanitize and validate all of the data in your $_POST and $_GET arrays using a definition array and a single function call. Imagine you have the following HTML form:

<form action="adduser.php" method="post">
    First Name: <input type="text" name="firstname" /><br/>
    E-mail: <input type="text" name="email" /><br/>
    Age: <input type="text" name="age" /><br/>
    <input type="submit" value="Add User" />

How can you use filter_input_array to ensure that the user is at least 18 years old, has entered a valid email address, and ensure that no malicious or dangerous characters are going to be inserted into your database? Here is an example using filter_input_array:

$options = array(
    'firstname'   => FILTER_SANITIZE_STRING,
    'age' => array(
                 'filter'    => FILTER_VALIDATE_INT,
                 'options'   => array('min_range' => 18)

$_CLEAN = filter_input_array(INPUT_POST, $options);

Now, you can access the validated and sanitized data in your $_CLEAN array instead of using $_POST directly, like so:

  $firstname = $_CLEAN["firstname"];
  if (!$_CLEAN["email"]) {
      // the email address was not valid, 
      // so display an error to the user
  // and so on...

I hope you’ve learned a little something about sanitizing your data. This (very long) post was only meant to steer you in the right direction – The best way to learn about PHP’s data filtering functionality is to read the manual and try it out for yourself!