Monday 23 February 2015

PHP: Generate a salt

<?php

/**
 * This function generates a password salt as a string of x (default = 15) characters
 * in the a-zA-Z0-9!@#$%&*? range.
 * @param $max integer The number of characters in the string
 * @return string
 *
 */
function generateSalt($max = 15) {
        $characterList = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*?";
        $i = 0;
        $salt = "";
        while ($i < $max) {
            $salt .= $characterList{mt_rand(0, (strlen($characterList) - 1))};
            $i++;
        }
        return $salt;
}

?>

PHP: Generate an alpha-numeric password salt

<?php
/**
 * This function generates an alpha-numeric password salt (with a default of 32 characters)
 * @param $max integer The number of characters in the string
 *
 */
function generateSalt($max = 32) {
$baseStr = time() . rand(0, 1000000) . rand(0, 1000000);
$md5Hash = md5($baseStr);
if($max < 32){
$md5Hash = substr($md5Hash, 0, $max);
}
return $md5Hash;
}

//Usage:
/*
echo "Salt with 32 characters:\n";
echo generateSalt() . "\n";
echo "Salt with 5 characters:\n";
echo generateSalt(5) . "\n";
*/
?>

Javascript: Client-side clock, based on computed time differential between browser and server.

<?php
/*** Clock -- beginning of server-side support code ***/

/* Prevent this page from being cached (though some browsers still
   cache the page anyway, which is why we use cookies). This is
   only important if the cookie is deleted while the page is still
   cached (and for ancient browsers that don't know about Cache-Control).
   If that's not an issue, you may be able to get away with
   "Cache-Control: private" instead. */
     header("Pragma: no-cache");

/* Grab the current server time. */
$gDate = time();
/* Are the seconds shown by default? When changing this, also change the
   JavaScript client code's definition of clockShowsSeconds below to match. */
$gClockShowsSeconds = false;

function getServerDateItems($inDate) {
return date('Y,n,j,G,',$inDate).intval(date('i',$inDate)).','.intval(date('s',$inDate));
// year (4-digit),month,day,hours (0-23),minutes,seconds
// use intval to strip leading zero from minutes and seconds
//   so JavaScript won't try to interpret them in octal
//   (use intval instead of ltrim, which translates '00' to '')
}

function clockDateString($inDate) {
    return date('l, F j, Y',$inDate);    // eg "Monday, January 1, 2002"
}

function clockTimeString($inDate, $showSeconds) {
    return date($showSeconds ? 'g:i:s' : 'g:i',$inDate).' ';
}
/*** Clock -- end of server-side support code ***/
?>
<html>
<head>
<title>Clock</title>
<meta name="template" content="none">
<script language="JavaScript" type="text/javascript">
<!--
/* set up variables used to init clock in BODY's onLoad handler;
   should be done as early as possible */
var clockLocalStartTime = new Date();
var clockServerStartTime = new Date(<?php echo(getServerDateItems($gDate))?>);

/* stub functions for older browsers;
   will be overridden by next JavaScript1.2 block */
function clockInit() {
}
//-->
</script>
<script language="JavaScript1.2" type="text/javascript">
<!--
/*** simpleFindObj, by Andrew Shearer

Efficiently finds an object by name/id, using whichever of the IE,
classic Netscape, or Netscape 6/W3C DOM methods is available.
The optional inLayer argument helps Netscape 4 find objects in
the named layer or floating DIV. */
function simpleFindObj(name, inLayer) {
return document[name] || (document.all && document.all[name])
|| (document.getElementById && document.getElementById(name))
|| (document.layers && inLayer && document.layers[inLayer].document[name]);
}

/*** Beginning of Clock 2.1.2, by Andrew Shearer
See: http://www.shearersoftware.com/software/web-tools/clock/
Redistribution is permitted with the above notice intact.

Client-side clock, based on computed time differential between browser &
server. The server time is inserted by server-side JavaScript, and local
time is subtracted from it by client-side JavaScript while the page is
loading.

Cookies: The local and remote times are saved in cookies named
localClock and remoteClock, so that when the page is loaded from local
cache (e.g. by the Back button) the clock will know that the embedded
server time is stale compared to the local time, since it already
matches its cookie. It can then base the calculations on both cookies,
without reloading the page from the server. (IE 4 & 5 for Windows didn't
respect Response.Expires = 0, so if cookies weren't used, the clock
would be wrong after going to another page then clicking Back. Netscape
& Mac IE were OK.)

Every so often (by default, one hour) the clock will reload the page, to
make sure the clock is in sync (as well as to update the rest of the
page content).

Compatibility: IE 4.x and 5.0, Netscape 4.x and 6.0, Mozilla 1.0. Mac & Windows.

History:  1.0   2000-05-09 GIF-image digits
          2.0   2000-06-29 Uses text DIV layers (so 4.0 browsers req'd), &
                         cookies to work around Win IE stale-time bug
 2.1   2002-10-12 Noted Mozilla 1.0 compatibility; released PHP version.
 2.1.1 2002-10-20 Fixed octal bug in the PHP translation; the number of
  minutes & seconds were misinterpretes when less than 10
 2.1.2 2003-08-07 The previous fix had introduced a bug when the
               minutes or seconds were exactly 0. Thanks to Man Bui
               for reporting the bug.
*/
var clockIncrementMillis = 60000;
var localTime;
var clockOffset;
var clockExpirationLocal;
var clockShowsSeconds = false;
var clockTimerID = null;

function clockInit(localDateObject, serverDateObject)
{
    var origRemoteClock = parseInt(clockGetCookieData("remoteClock"));
    var origLocalClock = parseInt(clockGetCookieData("localClock"));
    var newRemoteClock = serverDateObject.getTime();
    // May be stale (WinIE); will check against cookie later
    // Can't use the millisec. ctor here because of client inconsistencies.
    var newLocalClock = localDateObject.getTime();
    var maxClockAge = 60 * 60 * 1000;   // get new time from server every 1hr

    if (newRemoteClock != origRemoteClock) {
        // new clocks are up-to-date (newer than any cookies)
        document.cookie = "remoteClock=" + newRemoteClock;
        document.cookie = "localClock=" + newLocalClock;
        clockOffset = newRemoteClock - newLocalClock;
        clockExpirationLocal = newLocalClock + maxClockAge;
        localTime = newLocalClock;  // to keep clockUpdate() happy
    }
    else if (origLocalClock != origLocalClock) {
        // error; localClock cookie is invalid (parsed as NaN)
        clockOffset = null;
        clockExpirationLocal = null;
    }
    else {
        // fall back to clocks in cookies
        clockOffset = origRemoteClock - origLocalClock;
        clockExpirationLocal = origLocalClock + maxClockAge;
        localTime = origLocalClock;
        // so clockUpdate() will reload if newLocalClock
        // is earlier (clock was reset)
    }
    /* Reload page at server midnight to display the new date,
       by expiring the clock then */
    var nextDayLocal = (new Date(serverDateObject.getFullYear(),
            serverDateObject.getMonth(),
            serverDateObject.getDate() + 1)).getTime() - clockOffset;
    if (nextDayLocal < clockExpirationLocal) {
        clockExpirationLocal = nextDayLocal;
    }
}

function clockOnLoad()
{
    clockUpdate();
}

function clockOnUnload() {
    clockClearTimeout();
}

function clockClearTimeout() {
    if (clockTimerID) {
        clearTimeout(clockTimerID);
        clockTimerID = null;
    }
}

function clockToggleSeconds()
{
    clockClearTimeout();
    if (clockShowsSeconds) {
        clockShowsSeconds = false;
        clockIncrementMillis = 60000;
    }
    else {
        clockShowsSeconds = true;
        clockIncrementMillis = 1000;
    }
    clockUpdate();
}

function clockTimeString(inHours, inMinutes, inSeconds) {
    return inHours == null ? "-:--" : ((inHours == 0
                   ? "12" : (inHours <= 12 ? inHours : inHours - 12))
                + (inMinutes < 10 ? ":0" : ":") + inMinutes
                + (clockShowsSeconds
                   ? ((inSeconds < 10 ? ":0" : ":") + inSeconds) : "")
                + (inHours < 12 ? " AM" : " PM"));
}

function clockDisplayTime(inHours, inMinutes, inSeconds) {
 
    clockWriteToDiv("ClockTime", clockTimeString(inHours, inMinutes, inSeconds));
}

function clockWriteToDiv(divName, newValue) // APS 6/29/00
{
    var divObject = simpleFindObj(divName);
    newValue = '<p>' + newValue + '<' + '/p>';
    if (divObject && divObject.innerHTML) {
        divObject.innerHTML = newValue;
    }
    else if (divObject && divObject.document) {
        divObject.document.writeln(newValue);
        divObject.document.close();
    }
    // else divObject wasn't found; it's only a clock, so don't bother complaining
}

function clockGetCookieData(label) {
    /* find the value of the specified cookie in the document's
    semicolon-delimited collection. For IE Win98 compatibility, search
    from the end of the string (to find most specific host/path) and
    don't require "=" between cookie name & empty cookie values. Returns
    null if cookie not found. One remaining problem: Under IE 5 [Win98],
    setting a cookie with no equals sign creates a cookie with no name,
    just data, which is indistinguishable from a cookie with that name
    but no data but can't be overwritten by any cookie with an equals
    sign. */
    var c = document.cookie;
    if (c) {
        var labelLen = label.length, cEnd = c.length;
        while (cEnd > 0) {
            var cStart = c.lastIndexOf(';',cEnd-1) + 1;
            /* bug fix to Danny Goodman's code: calculate cEnd, to
            prevent walking the string char-by-char & finding cookie
            labels that contained the desired label as suffixes */
            // skip leading spaces
            while (cStart < cEnd && c.charAt(cStart)==" ") cStart++;
            if (cStart + labelLen <= cEnd && c.substr(cStart,labelLen) == label) {
                if (cStart + labelLen == cEnd) {              
                    return ""; // empty cookie value, no "="
                }
                else if (c.charAt(cStart+labelLen) == "=") {
                    // has "=" after label
                    return unescape(c.substring(cStart + labelLen + 1,cEnd));
                }
            }
            cEnd = cStart - 1;  // skip semicolon
        }
    }
    return null;
}

/* Called regularly to update the clock display as well as onLoad (user
   may have clicked the Back button to arrive here, so the clock would need
   an immediate update) */
function clockUpdate()
{
    var lastLocalTime = localTime;
    localTime = (new Date()).getTime();
 
    /* Sanity-check the diff. in local time between successive calls;
       reload if user has reset system clock */
    if (clockOffset == null) {
        clockDisplayTime(null, null, null);
    }
    else if (localTime < lastLocalTime || clockExpirationLocal < localTime) {
        /* Clock expired, or time appeared to go backward (user reset
           the clock). Reset cookies to prevent infinite reload loop if
           server doesn't give a new time. */
        document.cookie = 'remoteClock=-';
        document.cookie = 'localClock=-';
        location.reload();      // will refresh time values in cookies
    }
    else {
        // Compute what time would be on server
        var serverTime = new Date(localTime + clockOffset);
        clockDisplayTime(serverTime.getHours(), serverTime.getMinutes(),
            serverTime.getSeconds());
     
        // Reschedule this func to run on next even clockIncrementMillis boundary
        clockTimerID = setTimeout("clockUpdate()",
            clockIncrementMillis - (serverTime.getTime() % clockIncrementMillis));
    }
}

/*** End of Clock ***/
//-->
</script>
</head>

<body bgcolor="#FFFFFF"
    onload="clockInit(clockLocalStartTime, clockServerStartTime);clockOnLoad();"
    onunload="clockOnUnload()">
<div id="ClockTime" style="position: absolute; left: 406px; top: 28px;
    width: 200px; height: 20px; z-index: 11; cursor: pointer"
    onclick="clockToggleSeconds()">
  <p><?php echo(clockTimeString($gDate,$gClockShowsSeconds));?></p>
</div>
<div id="ClockBkgnd" style="position: absolute; left: 406px; top: 28px;
    width: 200px; z-index: 10">
  <p> <br>
  <?php echo(clockDateString($gDate));?></p>
</div>
<p><i>Click on the time to show or hide seconds.</i></p>
</body>
</html>

PHP: Common mistakes when creating secure PHP websites

Do you remember the last website which was hacked by some kids? What was your first thought, maybe “Phew, that’s not mine”? A hacked website is terrible and the clean-up is a lot of work for the site owner. As a website owner you need to be sure that your site is always secure. It’s important for your business and of course for your site listing in Google. Remember these tips when creating secure PHP websites:

MySQL queries and SQL injection attacks

If your web page accepts user input a SQL injection might happen if the data isn’t validated or sanitized before the database query is done. The following example is a common mistake, made by the beginning programmer or webmaster. Check this code, do you ever wrote a MySQL query like this one?

$result = mysql_query("SELECT * FROM users WHERE username = '". $_POST["username"] ."' && password = '". $_POST["password"] ."');

This row of code is written to accept two values from a login form: a user name and a password. But what if someone will submit an empty user name and for the password value the following string: ‘ OR username = ‘admin the query would look like:

$result = mysql_query("SELECT * FROM users WHERE username = '' && password = '' OR username = 'admin'"); 

If this query was used for a login script, the hacker would get access to the account for the user with the name “admin”. Imagine what a hacker could do in your web application if he has administrator rights. Don’t worry there are several ways to protect your queries against SQL injections.


First of all it’s better to use the MySQL improved extension (MySQLi). The old PHP functions for MySQL are still available, but the MySQLi extension offers more secure features. If you use the MySQLi functions you can choose between procedural style and the object oriented style. I use for my examples the object oriented style.


Before I escape the values for our queries we use the function filter_var() to sanitize the input values.
$username = filter_var($_POST["username"], FILTER_SANITIZE_STRING);
$password = filter_var($_POST["password"], FILTER_SANITIZE_STRING);
My example is using the default value for the filter type FILTER_SANITIZE_STRING. Next I use the MySQLi variant of mysql_real_escape_string() to prepare the strings for the database query. Before I can continue with the input validation, I need to create a database object first.

$db = new mysqli("localhost", "db_user", "db_password", "db_name");

if (mysqli_connect_errno()) { /* check connection */
    die("Connect failed: ".mysqli_connect_error());
}


$username = $db->mysqli_real_escape_string($username);


$password = $db->mysqli_real_escape_string($password);



Now it’s safe to pass these values to our database query:

$result = $db->query(sprintf("SELECT FROM users WHERE username = '%s' && password = '%s'", $username, $password));
$db->close();
In my example I used the function sprintf() to add the values to the query and use the $db->close() to destroy the database object. Another great and secure MySQLi feature the prepared statementsfunction.

Cross Site Request Forgery (CSRF) Attacks

The basic principal behind a CSRF attack is not to get access to a site, but forcing a user or admin to an unwanted action. For example we have an admin page with a HTML structure like this one.

<ul>


<li><a href="delete.php?page_id=10">delete home page</a></li>


<li><a href="delete.php?page_id=20">delete news page</a></li>


</ul>
We have protected the page named delete.php with some login script, that a user without permissions can’t access the page or script.
if( logged_in() == false ) {


// User not logged in


die();


} else {


// User logged in


$db->query(sprintf("DELETE FROM pages WHERE page_id = %d", $_GET['page_id']));


}

The script dies if the user isn’t logged in and otherwise the page with the page ID from the GET variable will be deleted. By using the function sprintf() I’m able to format the value to an integer value by using the type specifier %d. Seems to be safe or not?


Let’s say the authorized (logged in) would visit a page where a comment was posted including an image. If a hacker has posted an image with the URL like the one below you wouldn’t notice it, because the image doesn’t show up because the URL doesn’t exists.

<img src="http://www.yoururl.com/delete_page.php?page_id=20" />



Sure this is a very stupid example and the hack is only possible if the hacker knows your PHP website security. A much better solution would be to use a unique token for each important action. The best way is to create a unique token for the admin user during login. Let’s say the code below is a part from your login script. Inside the login_user() function I create a session variable than contains a md5() encrypted string.
session_start();



function logged_in() {


// your code to check a valid login


}


function login_user() {


// your authentication process


// comes


$id = md5(uniqid(mt_rand(), true));


$_SESSION['token'] = $id;


}


function get_token() {


return (!empty($_SESSION['token'])) ? $_SESSION['token'] : 0;


}



Inside the page with the HTML structure I need to add the token variables after each link.


$token = get_token();


echo '


<ul>


<li><a href="delete.php?page_id=10&token='.$token.'">delete home page</a></li>


<li><a href="delete.php?page_id=20&token='.$token.'">delete news page</a></li>


</ul>';



With this additional token variable inside the delete.php script I’m able to validate the data input.

if( logged_in() == false ) {


// User not logged in


die();


} else {


// User logged in


if (empty($_GET['token']) || $_GET['token'] != $_SESSION['token']) {


die();


} else {


$db->query(sprintf("DELETE FROM pages WHERE page_id = %d", $_GET['page_id']));


}


}

This simple validation will stop the script if the token is missing or not equal to the token session variable.
Cross site scripting (XSS) Attacks


The basic idea of XSS attack is that a hacker has embedded some client-side code on your web site which is executed or download by a visitor. This happens in different ways. For example by using a link to your website where some malicious JavaScript is added or the hacker has posted some JavaScript code to your website. The last one happens mostly by using unsafe comment forms where the content find a place on your website.


In any situation it’s important that your web application sanitizes the user’s input before the data is stored or parsed in your web page. Use different validation functions like preg_match(), filter_var() or better htmlspecialchars() to filter or convert possible attacks from hackers. The function htmlspecialchars() will convert HTML tags into entities.
Limit script functionality


If your website has a login function, it’s possible that a hacker will use a script that will try guess a user name and password. While using thousands of combinations it’s possible that the hacker will succeed. Throttle down the access to your login page if a visitor has made more than X submissions and use always passwords which are hard to guess. Common passwords like “welcome” or “default” are most of the time the cause of getting hacked.


Be careful with the function to recover a password. Never send the recovery instructions to some new email address and let the owner of the registered email address execute the recovery action.


Captcha images are a great and simple way to stop bots accessing your web forms. Use them where a remote submission can harm your web application.
Disable PHP error reporting


There are many reasons why some PHP error can happen on a website. Many of them doesn’t have any influence on the web site’s functionality. For a hacker is a notice or error message a source to get information about your website and/or sever configuration. Test your website always for possible error, because they are bad for your website and/or business, too. Would you trust a service that is broken?

There is also a functions that disables the output of error messages, add error_reporting(0); to your script and allow error reporting ONLY on your test location!


I hope this tutorial helps to understand some basic concepts how a hacker will try to attack your websites. Don’t make these mistakes when creating secure PHP websites!

PHP: Capture the requested URI and Clean up global variables

<?php
$requestURI = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']';
echo $requestURI;
?>

This snippet is more of an example of how to convert strings to lowercase characters, and then clean them up for use in scripts, etc
<?php
$_POST["name"] = strtolower(stripslashes(trim(htmlspecialchars($_POST["name"])))); $_POST["message"] = strtolower(stripslashes(trim(htmlspecialchars($_POST["message"]))));
?>

PHP: Detect browser language

If your website is multilingual, it can be useful to detect the browser language to use this language as the default. The code below will return the language used by the client’s browser.

function get_client_language($availableLanguages, $default='en'){
 if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
  $langs=explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']);

  foreach ($langs as $value){
   $choice=substr($value,0,2);
   if(in_array($choice, $availableLanguages)){
    return $choice;
   }
  }
 } 
 return $default;

PHP: WORDPRESS - Auto convert URL into clickable hyperlink

In wordpress, if you want to auto convert all URLs in your string into clickable hyperlinks, you can actually do it using the built-in function make_clickable(). If you need to do that outside of wordpress, you can refer to the function’s source code at wp-includes/formatting.php:

<?php

function _make_url_clickable_cb($matches) {

$ret = '';

$url = $matches[2];



if ( empty($url) )

return $matches[0];

// removed trailing [.,;:] from URL

if ( in_array(substr($url, -1), array('.', ',', ';', ':')) === true ) {

$ret = substr($url, -1);

$url = substr($url, 0, strlen($url)-1);

}

return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>" . $ret;

}



function _make_web_ftp_clickable_cb($matches) {

$ret = '';

$dest = $matches[2];

$dest = 'http://' . $dest;



if ( empty($dest) )

return $matches[0];

// removed trailing [,;:] from URL

if ( in_array(substr($dest, -1), array('.', ',', ';', ':')) === true ) {

$ret = substr($dest, -1);

$dest = substr($dest, 0, strlen($dest)-1);

}

return $matches[1] . "<a href=\"$dest\" rel=\"nofollow\">$dest</a>" . $ret;

}



function _make_email_clickable_cb($matches) {

$email = $matches[2] . '@' . $matches[3];

return $matches[1] . "<a href=\"mailto:$email\">$email</a>";

}



function make_clickable($ret) {

$ret = ' ' . $ret;

// in testing, using arrays here was found to be faster

$ret = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_url_clickable_cb', $ret);

$ret = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_web_ftp_clickable_cb', $ret);

$ret = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret);



// this one is not in an array because we need it to run last, for cleanup of accidental links within links

$ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);

$ret = trim($ret);

return $ret;

}

?>

PHP: Find All Links on a Page

Using the DOM, you can easily grab all links from any webpage. Here’s a working example:
<?php
$html = file_get_contents('http://www.example.com');

$dom = new DOMDocument();
@$dom->loadHTML($html);

// grab all the on the page
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate("/html/body//a");

for ($i = 0; $i < $hrefs->length; $i++) {
       $href = $hrefs->item($i);
       $url = $href->getAttribute('href');
       echo $url.'<br />';
}
?>

PHP: Extract keywords from a webpage

The title said it all: A great code snippet to easily extract meta keywords from any webpage.
<?php
$meta = get_meta_tags('https://thiscode4u.blogspot.com/');
$keywords = $meta['keywords'];
// Split keywords
$keywords = explode(',', $keywords );
// Trim them
$keywords = array_map( 'trim', $keywords );
// Remove empty values
$keywords = array_filter( $keywords );

print_r( $keywords );
?>

Unzip files with PHP

The following function takes two parameters: The .zip file to unzip, and the destination directory.
<?php
function unzip_file($file, $destination){ 
// create object 
$zip = new ZipArchive() ; 
// open archive 
if ($zip->open($file) !== TRUE) { 
die ('Could not open archive'); 
}
 // extract contents to destination directory 
$zip->extractTo($destination); 
// close archive $zip->close();
 echo 'Archive extracted to directory'; 
}
?>

PHP: Generate CSV file from a PHP array

Here is a simple but efficient function to generate a .csv file from a PHP array. The function accept 3 parameters: the data, the csv delimeter (default is a comma) and the csv enclosure (default is a double quote).
<?php
function generateCsv($data, $delimiter = ',', $enclosure = '"') { 
$handle = fopen('php://temp', 'r+'); 
foreach ($data as $line) { 
fputcsv($handle, $line, $delimiter, $enclosure);
 } 
rewind($handle); 
while (!feof($handle)) { 
$contents .= fread($handle, 8192); 
}
 fclose($handle); 
return $contents; 
}
?>

PHP: Sanitize database inputs

In order to keep your database safe, you have to be very careful about the input you’re going to save. Here is a super handy function which sanitize inputs to make sure you’re not inserting malicious code into your database.
function cleanInput($input) {
 
  $search = array(
    '@<script[^>]*?>.*?</script>@si',   // Strip out javascript
    '@<[\/\!]*?[^<>]*?>@si',            // Strip out HTML tags
    '@<style[^>]*?>.*?</style>@siU',    // Strip style tags properly
    '@<![\s\S]*?--[ \t\n\r]*>@'         // Strip multi-line comments
  );
 
    $output = preg_replace($search, '', $input);
    return $output;
  }

function sanitize($input) {
    if (is_array($input)) {
        foreach($input as $var=>$val) {
            $output[$var] = sanitize($val);
        }
    }
    else {
        if (get_magic_quotes_gpc()) {
            $input = stripslashes($input);
        }
        $input  = cleanInput($input);
        $output = mysql_real_escape_string($input);
    }
    return $output;
}

// Usage:
$bad_string = "Hi! <script src='https://thiscode4u.blogspot.com/bad_script.js'></script> It's a good day!";
  $good_string = sanitize($bad_string);
  // $good_string returns "Hi! It\'s a good day!"

  // Also use for getting POST/GET variables
  $_POST = sanitize($_POST);
  $_GET  = sanitize($_GET);
?>

PHP: Some important PHP Snippets


PHP have lots of built-in functions, and most developers know many of them. But a few functions are not very well known, but are super useful. In this article, I have compiled little known but really cool PHP functions.

highlight_string()
When displaying PHP code on a website, the highlight_string() function can be really helpful: It outputs or returns a syntax highlighted version of the given PHP code using the colors defined in the built-in syntax highlighter for PHP.
Usage:
<?php
highlight_string('<?php phpinfo(); ?>');
?>
str_word_count()
This handy function takes a string as a parameter and return the count of words, as shown in the example below.
Usage:
?php
$str = "How many words do I have?";
echo str_word_count($str); //Outputs 5
?>
levenshtein()
Ever find the need to determine how different (or similar) two words are? Then levenshtein() is just the function you need. This function can be super useful to track user submitted typos.
Usage:
<?php
$str1 = "carrot";
$str2 = "carrrott";
echo levenshtein($str1, $str2); //Outputs 2
?>
get_defined_vars()
Here is a handy function when debugging: It returns a multidimensional array containing a list of all defined variables, be them environment, server or user-defined variables, within the scope that get_defined_vars() is called.
Usage:
print_r(get_defined_vars());
escapeshellcmd()
escapeshellcmd() escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands. This function should be used to make sure that any data coming from user input is escaped before this data is passed to the exec() or system() functions, or to the backtick operator.
Usage:
<?php
$command = './configure '.$_POST['configure_options'];

$escaped_command = escapeshellcmd($command);
 
system($escaped_command);
?>
checkdate()
Checks the validity of the date formed by the arguments. A date is considered valid if each parameter is properly defined. Pretty useful to test is a date submitted by an user is valid.
Usage:
<?php
var_dump(checkdate(12, 31, 2000));
var_dump(checkdate(2, 29, 2001));

//Output
//bool(true)
//bool(false)
?>
php_strip_whitespace()
Returns the PHP source code in filename with PHP comments and whitespace removed. This is similar to using php -w from the commandline.
Usage:
<?php
// PHP comment here

/*
 * Another PHP comment
 */

echo        php_strip_whitespace(__FILE__);
// Newlines are considered whitespace, and are removed too:
do_nothing();
?>
The output:
<?php
 echo php_strip_whitespace(__FILE__); do_nothing(); ?

Add (th, st, nd, rd, th) to the end of a number

Another useful snippet which will automatically add st, nd, rd or th after a number.
<?php
function make_ranked($rank) {
 $last = substr( $rank, -1 );
 $seclast = substr( $rank, -2, -1 );
 if( $last > 3 || $last == 0 ) $ext = 'th';
 else if( $last == 3 ) $ext = 'rd';
 else if( $last == 2 ) $ext = 'nd';
 else $ext = 'st'; 

 if( $last == 1 && $seclast == 1) $ext = 'th';
 if( $last == 2 && $seclast == 1) $ext = 'th';
 if( $last == 3 && $seclast == 1) $ext = 'th'; 

 return $rank.$ext;
}
?>

Maintenance mode with PHP

When updating your site, it is generally a good thing to temporarily redirect your users to a “Maintenance” page so they will not see any critical info such as error messages.

This is generally done using an .htaccess file, but it can be done easily with PHP:
<?php
function maintenance($mode = FALSE){
    if($mode){
        if(basename($_SERVER['SCRIPT_FILENAME']) != 'maintenance.php'){
            header("Location: http://example.com/maintenance.php");
            exit;
        }
    }else{
        if(basename($_SERVER['SCRIPT_FILENAME']) == 'maintenance.php'){
            header("Location: http://example.com/");
            exit;
        }
    }
}
?>

Calculate execution time

For debugging purposes, it is a good thing to be able to calculate the execution time of a script. This is exactly what this piece of code can do.

<?php
//Create a variable for start time
$time_start = microtime(true);

// Place your PHP/HTML/JavaScript/CSS/Etc. Here

//Create a variable for end time
$time_end = microtime(true);
//Subtract the two times to get seconds
$time = $time_end - $time_start;

echo 'Script took '.$time.' seconds to execute';
?>

PHP: Automatic password creation

Although I personally prefer leaving users to choose their password themselves, a client recently asked me to generate passwords automatically when a new account is created.

The following function is flexible: You can choose the desired length and strength for the password.

<?php
function generatePassword($length=9, $strength=0) {
 $vowels = 'aeuy';
 $consonants = 'bdghjmnpqrstvz';
 if ($strength >= 1) {
  $consonants .= 'BDGHJLMNPQRSTVWXZ';
 }
 if ($strength >= 2) {
  $vowels .= "AEUY";
 }
 if ($strength >= 4) {
  $consonants .= '23456789';
 }
 if ($strength >= 8 ) {
  $vowels .= '@#$%';
 }

 $password = '';
 $alt = time() % 2;
 for ($i = 0; $i < $length; $i++) {
  if ($alt == 1) {
   $password .= $consonants[(rand() % strlen($consonants))];
   $alt = 0;
  } else {
   $password .= $vowels[(rand() % strlen($vowels))];
   $alt = 1;
  }
 }
 return $password;
}
?>

PHP: Highlight specific words in a phrase

Sometimes, for example, when displaying search results, it is a great idea to highlight specific words. This is exactly what the following function can do:

<?php

function highlight($sString, $aWords) {

 if (!is_array ($aWords) || empty ($aWords) || !is_string ($sString)) {
  return false;
 }

 $sWords = implode ('|', $aWords);
  return preg_replace ('@\b('.$sWords.')\b@si', '<strong style="background-color:yellow">$1</strong>', $sString);
}
?>

Email PHP errors instead of displaying it

By default, most servers are set to display an error message when an error occured in one of your script. For security reasons, you may want to get an email with the error, instead of displaying it to the public.

<?php
// Our custom error handler
function nettuts_error_handler($number, $message, $file, $line, $vars){
 $email = "
  <p>An error ($number) occurred on line
  <strong>$line</strong> and in the <strong>file: $file.</strong>
  <p> $message </p>";

 $email .= "<pre>" . print_r($vars, 1) . "</pre>";

 $headers = 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

 // Email the error to someone...
 error_log($email, 1, 'you@youremail.com', $headers);

 // Make sure that you decide how to respond to errors (on the user's side)
 // Either echo an error message, or kill the entire project. Up to you...
 // The code below ensures that we only "die" if the error was more than
 // just a NOTICE.
 if ( ($number !== E_NOTICE) && ($number < 2048) ) {
  die("There was an error. Please try again later.");
 }
}

// We should use our custom function to handle errors.
set_error_handler('nettuts_error_handler');

// Trigger an error... (var doesn't exist)
echo $somevarthatdoesnotexist;
?>

Whois query using PHP

If you need to get the whois information for a specific domain, why not using PHP to do it? The following function take a domain name as a parameter, and then display the whois info related to the domain.
<?php
function whois_query($domain) {
 
    // fix the domain name:
    $domain = strtolower(trim($domain));
    $domain = preg_replace('/^http:\/\//i', '', $domain);
    $domain = preg_replace('/^www\./i', '', $domain);
    $domain = explode('/', $domain);
    $domain = trim($domain[0]);
 
    // split the TLD from domain name
    $_domain = explode('.', $domain);
    $lst = count($_domain)-1;
    $ext = $_domain[$lst];
 
    // You find resources and lists 
    // like these on wikipedia: 
    //
    // <a href="http://de.wikipedia.org/wiki/Whois">http://de.wikipedia.org/wiki/Whois</a>
    //
    $servers = array(
        "biz" => "whois.neulevel.biz",
        "com" => "whois.internic.net",
        "us" => "whois.nic.us",
        "coop" => "whois.nic.coop",
        "info" => "whois.nic.info",
        "name" => "whois.nic.name",
        "net" => "whois.internic.net",
        "gov" => "whois.nic.gov",
        "edu" => "whois.internic.net",
        "mil" => "rs.internic.net",
        "int" => "whois.iana.org",
        "ac" => "whois.nic.ac",
        "ae" => "whois.uaenic.ae",
        "at" => "whois.ripe.net",
        "au" => "whois.aunic.net",
        "be" => "whois.dns.be",
        "bg" => "whois.ripe.net",
        "br" => "whois.registro.br",
        "bz" => "whois.belizenic.bz",
        "ca" => "whois.cira.ca",
        "cc" => "whois.nic.cc",
        "ch" => "whois.nic.ch",
        "cl" => "whois.nic.cl",
        "cn" => "whois.cnnic.net.cn",
        "cz" => "whois.nic.cz",
        "de" => "whois.nic.de",
        "fr" => "whois.nic.fr",
        "hu" => "whois.nic.hu",
        "ie" => "whois.domainregistry.ie",
        "il" => "whois.isoc.org.il",
        "in" => "whois.ncst.ernet.in",
        "ir" => "whois.nic.ir",
        "mc" => "whois.ripe.net",
        "to" => "whois.tonic.to",
        "tv" => "whois.tv",
        "ru" => "whois.ripn.net",
        "org" => "whois.pir.org",
        "aero" => "whois.information.aero",
        "nl" => "whois.domain-registry.nl"
    );
 
    if (!isset($servers[$ext])){
        die('Error: No matching nic server found!');
    }
 
    $nic_server = $servers[$ext];
 
    $output = '';
 
    // connect to whois server:
    if ($conn = fsockopen ($nic_server, 43)) {
        fputs($conn, $domain."\r\n");
        while(!feof($conn)) {
            $output .= fgets($conn,128);
        }
        fclose($conn);
    }
    else { die('Error: Could not connect to ' . $nic_server . '!'); }
 
    return $output;
}
?>

Compress data using gzcompress()

When working with strings, it is not rare that some are very long. Using the gzcompress() function, strings can be compressed. To uncompressed it, simply call the gzuncompress() function as demonstrated below


<?php
$string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ut elit id mi ultricies adipiscing. Nulla facilisi. Praesent pulvinar, sapien vel feugiat vestibulum, nulla dui pretium orci, non ultricies elit lacus quis ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam pretium ullamcorper urna quis iaculis. Etiam ac massa sed turpis tempor luctus. Curabitur sed nibh eu elit mollis congue. Praesent ipsum diam, consectetur vitae ornare a, aliquam a nunc. In id magna pellentesque tellus posuere adipiscing. Sed non mi metus, at lacinia augue. Sed magna nisi, ornare in mollis in, mollis sed nunc. Etiam at justo in leo congue mollis. Nullam in neque eget metus hendrerit scelerisque eu non enim. Ut malesuada lacus eu nulla bibendum id euismod urna sodales. ";

 $compressed = gzcompress($string); 
 echo "Original size: ". strlen($string)."\n"; /* prints Original size: 800 */ 
 echo "Compressed size: ". strlen($compressed)."\n"; /* prints Compressed size: 418 */
 // getting it back 
$original = gzuncompress($compressed);
?>

PHP: Get info about your memory usage

In order to optimize your scripts, you may definitely want to know how many amount of RAM they use on your server. This snippet will check memory and then print initial, final and peak usages.<?php

echo "Initial: ".memory_get_usage()." bytes \n";
/* prints
Initial: 361400 bytes
*/

// let's use up some memory
for ($i = 0; $i < 100000; $i++) {
 $array []= md5($i);
}

// let's remove half of the array
for ($i = 0; $i < 100000; $i++) {
 unset($array[$i]);
}

echo "Final: ".memory_get_usage()." bytes \n";
/* prints
Final: 885912 bytes
*/

echo "Peak: ".memory_get_peak_usage()." bytes \n";
/* prints
Peak: 13687072 bytes
*/
?>

PHP: Display source code of any webpage

Want to be able to display the source code of any webpage, with line numbering? 
Here is a simple code snippet to do it. Just modify the url on line 2 at your convenience. 
Or even better, make a pretty function according to your needs.
<?php // display source code
$lines = file('http://google.com/');
foreach ($lines as $line_num => $line) { 
 // loop thru each line and prepend line numbers
 echo "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "
\n";
}
?>

Thursday 19 February 2015

PHP select box multiple selections

<form action="<?=$_SERVER['PHP_SELF']?>" method="post">
<select name="test[]" multiple="multiple">
 <option value="one">one</option> 
<option value="two">two</option>
 <option value="three">three</option>
 <option value="four">four</option>
 <option value="five">five</option> 
</select> 
<input type="submit" value="Send" /> 
</form>


<?php
 $test=$_POST['test'];
 if ($test){
       foreach ($test as $t){
           echo 'You selected ',$t,'<br />';
        }
 } ?>

Monday 2 February 2015

PHP Basics

PHP is a scripting language that can be embedded in HTML.
  1. Tags and SyntaxPHP commands are embedded into HTML by one of several ways. The preferred method is include the code using the special tags <?php PHP_code_goes_here ?>. A second way is to include the code within a <script language="php"?> - </script> block. Each PHP statement should end with a semicolon. Many statements can be contained in a single block and a single statement can span several blocks:
    <?php
    if ($condition) {
       ?>
       <b>This is true.</b>
       <?php
    } else {
       ?>
       <b>This is false.</b>
       <?php
    }?>

    Comments are supported in the normal C/C++ and Java style:

    <?php
    echo "This is a test"; //This is a one-line comment. 
    /* This is a multi-line
    comment */
    ?>

  2. Variables and Datatypes
    Variables in PHP are represented by a dollar sign followed by an alphanumeric name beginning in a letter or underscore. Variable names are case sensitive. Variables do not need to be declared and their datatypes are inferred from the assignment statement.
    PHP supports the following data types:
    • boolean
    • integer
    • float
    • string
    • array
    • object
    • resource
    • NULL

    Example:
    <?php
    $bool = TRUE;
    $name = "Craig";
    $age = 25;
    $pi = 3.14159;
    echo $name . ' is ' . $age . ' years old.';
    ?>
    -> Craig is 25 years old.
    Variable Scope: The single scope of most variables in PHP spans the entire file plus any included files. For instance if you define $a = 1; then a will be available within any included files. 
    Local Variables: Any variable used inside a user-defined function, however, has its scope limited to the local function. In addition, global variables are not available inside local functions unless declared with the global keyword: 
    $a = 1;
    $b = 2;
    function Sum() {
       global $a, $b;
       $b = $a + $b; }
    Sum();
    Pointers can be assigned with an ampersand sign: $a = &$b;

  3. Statements and Expressions
    Some basic PHP statements include:
    • echo: Output one or more strings.
    • print: Also output one or more strings.
    • The assignment statement: Assigns a value to a variable.
    • include: Include and evaluate the specified file.
    • require: Same as include except it produces a fatal error on failure instead of a warning.

    Examples:
    echo "Hello World.";
    echo "Text can span
    multiple lines. Newlines will be
    output as well or can be done \nlike this.";
    echo $bool ? 'true' : 'false'
    $a = ($b = 5) + 4;
     // a = 9, b = 5
    echo $a,$b;
    $c = 'A equals ' . $a;
    print $c;
    include 'test.php'
     // The code in test.php will be evaluated here
    PHP expressions can include:
    $a = $b = 5; //The assignment statement
    $b = $a++; //Post-increment a
    $b = ++$a; //Pre-increment a
    $x = $bool ? $a : $b; //Ternery conditional
    The last expression evaluates to if ($bool) $x = $a else $x = $b.

  4. Operators and Maths
    Operators:
    • Arithmatic: +, -, *, /, and % (modulus)
    • Comparison: ==, !=, <, >, <=, >=
    • Logical: &&, And; ||, Or; ! (NOT); Xor
    • Execution: $output = `ls -l`;
         echo $output;
       //commands enclosed with backticks are executed and returned
    • Type: $obj = new A;
         if ($thing instanceof A) echo 'A';
    Maths:
    • Absolute Value: $a = abs(-7.5);
    • Arc sine: $x = asin(0.5); //returns in rads
    • Ceil (round up): echo ceil(4.2);
    • Cosine: $a = cos($x); //$x in rads
    • Deg2rad: $a = cos(deg2rad(45)); //cos 45 deg
    • Exp: $y = exp($x); //y=e^x
    • Floor (round down): $a = floor($a+0.5);
    • Is_Finite: $bool = is_finite($x);
    • Is_Infinite: $bool = is_infinite(log(0));
    • Is_NAN: $bool = is_nan(acos(1.01));
    • Log: $x = log($y); //Natural Log
         $x = log($y,5); //Base-5 log
    • Log Base 10: $x = log10($y);
    • Max: $mx = max(1, 7, 3, 4); //7
         $mx = max($arr); //max value in array
    • Min: $mn = min(3, 0, -1, $x); //min value
    • Powers: $x = pow($y,3); //x=y^3
    • Rad2deg: $a = rad2deg(asin(0.5)); //$a = 30
    • Random #: $x = mt_rand(1,100); //int 1-100, inclusive
         $x = rand(1,100)/100. //slower than mt_rand
    • Round: echo round(3.793,1); //3.8 - rounded to 1 decimal
         $a = round(3.793,0); //4
    • Sine: $a = sin(1.57); //in rads
    • Square Root: $x = sqrt(10); //3.16...
    • Tangent: echo tan(3.14); //in rads

  5. Strings
    Strings can be specified in 3 ways: single quotes, double quotes, or heredoc. Strings in single quotes do not expand variables or escape sequences except for single quotes: echo 'I\'ll be back.';.
    echo 'The newline \n will not expand';
    $a = 'Gators';
    echo 'The value of $a is ' . $a;

    -> The value of $a is Gators
    If a string is enclosed in double quotes, escapes such as \n, \r, \t, \\, and \" may be used and variables are expanded:echo "Go $a";
    -> Go Gators
    echo "{$a}bait!";
    -> Gatorbait!
    Heredoc syntax: Starts with <<< followed by an identifier. Ends with the identifier repeated at the start of a line.
    echo <<<ABC
    This is an example of a string in the heredoc syntax.
    Always use braces around arrays when inside of strings:
    The 3rd person's name is {$people['names'][3]}
    ABC;

    String Operators:
    Concatenation is done with the '.' operator.
    Converting to numbers:
    $x = 1 + "10.5"; //$x=11.5, float
    $x = 4 - "3"; //$x=1, int
    You can convert to a string with the (string) cast or thestrval function Booleans are converted to strings as "1" or "" (empty string). Values are also converted to strings when a string is needed, such as when using the echo or print functions.
    String Functions:
    • array explode(string separator, string string [,int limit]): parse a string into an array
        $pizza = "piece1 piece2 piece3";
         $pieces = explode(" ", $pizza);
    • string implode(string glue, array pieces): combine array elements into a string
        $array = array('name', 'email', 'phone');
         $comma_separated = implode(",", $array);
    • string str_replace(string search, string replace, string subject [,int count]):
        $bodytag = str_replace("%body%", "black", "text='%body%'");
        -> text='black'
        $vowels = array("a", "e", "i", "o", "u");
         $novowels = str_replace($vowels, "", "Hello World of PHP");

        -> Hll Wrld f PHP
    • str_ireplace: Case-insensitive version of str_replace.
    • string str_repeat(string input, int multiplier):
        echo str_repeat(" ",10);
    • array str_split(string string [,int split_length]):
        $arr = str_split("ABCDEFGHIJKL",3); //$arr[0]="ABC" ... $arr[3]="JKL"
    • int strcmp(string str1, string str2): returns <0 if str1 is less than str2, 0 if they are equal, and >0 if str1 is greater.
        if (strcmp($s1,$s2) > 0) echo "greater";
    • int strncmp(string str1, string str2, int len): Same as strcmp except it compares only the first len characters.
    • int strlen(string str): returns the length of a string
        $n = strlen($s);
    • int strpos(string haystack, string needle [,int offset]): Returns the numeric position of the first occurance of needle in haystack. Returns FALSE if needle is not found. Because position 0 also evaluates to FALSE, check with '===' and '!==' (identical value and type instead of equality).
        $p = strpos("This is a test","is");
         if ($p !== false) echo 'Position ' . $p;
    • int stripos(string haystack, string needle [,int offset]): Same as strpos but case insensitive.
    • string strtolower(string str): Convert a string to lowercase.
    • string strtoupper(string str): Convert a string to uppercase.
    • string substr(string string, int start [,int length]): Return a substring of string. A negative value for start results in starting at the nth character from the end of the string.
        echo substr("abcdef",1,3); //bcd
    • string trim(string str): Strip whitespace from the beginning and end of a string.

  6. Arrays
    Arrays in PHP are actually ordered maps, almost like hash tables. They map values to keys that can be either integers or strings.
    • Defining with array(): An array can be defined defined by the keyword array array([key => ]values):
      $arr = array(0 => 5, 3 => "text", "test" => true); 
      -> $arr[0]=5, $arr[3]="text", $arr["test"]=true 
      If no key is specified, then 1 + the maximum integer key is taken for the new key. The first element defaults to 0 if no key is given.
      $arr = array(0,1,4,9,16,25); //a 6-element array with each value equal to the square of its key.
      $arr = array(3 => 24, "a" => 32, 40, 48);
      -> $arr[3]=24; $arr["a"]=32; $arr[4]=40; $arr[5]=48 
    • Defining with []: You can also define an array or add values to it using the [] notation:
      $arr[5] = 100;
      This will set $arr[5] to 100, overwriting any previous value of $arr[5]. If $arr does not exist yet, it will be created.
      $arr = array(3, 12 => 2);
      $arr[] = 19;
      $arr[0] = "some text";
      $arr["x"] = 5;

      -> $arr[0] = "some text" (replacing 3), $arr[12] = 2, $arr[13] = 19, $arr["x"] = 5
    • Deleting values with unset(): The function unset() allows you to delete elements from an array.
      $a = array(1 => 'one', 2 => 'two', 3 => 'three');
      unset($a[2]);

      -> $array[1]='one', $array[3]='three' Note that $array[2] no longer exists but the other keys and elements are unaffected.
    • Multi-dimensional arrays: Because PHP arrays are actually ordered maps, you are allowed to have jagged arrays:
      $arr = array("fruits" => array ( "a" => "orange", "b" => "banana", "c" => "apple"),
      "numbers" => array(1, 2, 3, 4, 5, 6),
      "holes => array("first", 5 => "second", "third")); 
      -> $arr["fruits"]["b"] = "banana"; $arr["numbers"][4]=5; $arr["holes"][6]="third"... 
      $a = array(0, 1, 2, 3);
      $var = 5;
      $b = array("a" => $a, "var" => $var, 3 => array("first", "second", "third")); 

      -> $b["a"][2]=2; $b["var"]=5; $b[3][1]="second"...
    Array Operators:
    • Union: $a + $b
      The + operator appends the array on the right ($b) to the array on the left ($a) and duplicate keys are thrown away and not overwritten.
      $a = array(3, "a" => "Roberson", "b" => "Walsh");
      $b = array(4, "a" => "Lee", "c" => "Humphrey");
      -> $a+$b = {3, "a" => "Roberson", "b" => "Walsh", "c" => "Humphrey"}
      $b+$a = {4, "a" => "Lee", "b" => "Walsh", "c" => "Humphrey"}
    • Equality: $a == $b and Inequality: $a != $b
      $a is equal to $b if their elements all have the same key and value. The following two arrays are equal:
      $a = array("apple", "banana");
      $b = array(1 => "banana", "0" => "apple");
    • Idendical: $a === $b and Not Identical: $a !== $b
      $a is identical to $b if they have the same elements in the same order.
    Array Functions:
    • array array_combine(array keys, array values): creates a new array by using one existing array for keys and another for values. Returns false if it fails.
        $a = array('a','b','c');
         $b = array('red','green','blue');
         $c = array_combine($a, $b);
    • array array_flip(array input): swaps the keys and values of the array input. All values from input must be valid keys (integer or string). If a value occurs more than once, the latest key will be used as its value and all others will be thrown away. Returns false if it fails.
        $a = array("a" => 1, "b" => 2, "c" => 2);
      $b = array_flip($a);

        -> $b = {1 => "a", 2 => "c"}
    • array array_keys(array input [,mixed search_value]): returns all keys from the input array as the values of a new array. The new array has keys numbered from 0 to n_elements-1. If a search_value is specified, then only the keys for that value are returned.
        $a = array (0 => 100, "color" => "orange");
         $b = array("blue", "red", "blue", "green");
        -> array_keys($a) = {0, "color"}
         array_keys($b, "blue") = {0, 2}
    • array array_merge(array array1, array array2 [, array ...]): merges the elements of multiple arrays into one array. If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. However, if the arrays contain the same numeric keys, the later value will be appended with a new numeric key.
    • mixed array_pop(array array): pops and returns the last value of the array, shortening the array by one element. NULL is returned from an empty array.
        $var = array_pop($arr);
    • int array_push(array array, mixed var [,mixed ...]): pushes the variable(s) onto the end of array. Same effect as $arr[] = $var;. Returns the new number of elements in the array.
        array_push($arr, "Roberson", "Walsh");
    • array array_reverse(array array [,bool preserve_keys]): reverses the order of elements in the array. If preserve_keys is TRUE, the keys will be preserved in the reversed array.
    • mixed array_search(mixed needle, array haystack): Searches the array haystack for needle and returns the key if it is found and false otherwise.
        $key = array_search('Lee',$players);
    • mixed array_shift(array array): pops the first element out of the array and returns it. All numerical keys in the rest of the array will be modified to start counting from zero, while string keys won't be touched.
    • mixed array_sum(array array): returns the sum of the values in the array as an int or float.
    • int count(mixed var [,int mode]): Returns the number of elements in var if var is an array, and returns 1 if var is not an array. Returns 0 if var is null. If mode is set to 1, then count will recursively count the array. This is useful for counting all elements in a multi-dimensional array. Each subarray and element will be counted though so a 2x3 array will return 8 when counted recursively (and 2 when counted normally).
    • bool sort(array array): Sorts an array from lowest to highest. New keys will be assigned for the elements in array (numeric, starting with zero) and any existing keys will be removed. Returns true or false. Other types of sort include:
      • asort: Sort an array and maintain the current keys.
      • ksort: Sort an array by key instead of by value.
      • rsort: Sort an array in reverse order (highest to lowest).
      • arsort: Sort an array in reverse order and maintain keys.

  7. Conditionals
    • if: if (expr) statement;
    • if-else: if (expr) statement1; else statement2;
    • if-elseif: if (expr) statement1;
         elseif (expr) statement2;
         else statement3;
      Multiple elseifs can be included in the same if statement.
    • switch: switch($var) {
         case 0: statements;
         break;
         case "n": statements;
         break;
         default: statements;
        }
      Note that if you do not include the break; statement, PHP will continue to execute code for the next cases until it encounters a break;.

    Examples:
    if ($a > $b) echo "a is greater than b";

    if ($a > $b) {
       echo "a is greater than b";
    } elseif ($a < $b) {
       echo "a is less than b";
    } else {
       echo "a is equal to b";
    }

    switch ($a) {
      case 0:
        echo "i equals 0";
        break;
      case 1:
        echo "i equals 1";
      case 2:
        echo "i is greater than 0 and less than 3";
        break;
      case "a":
        echo "i equals a";
        break;
      default:
        echo "i does not equal 0,1,2, or a.";
    }

  8. Loops
    • for: for (expr1; expr2; expr3) statements;
      Same syntax as Java/C++. expr1 sets the initial condition and the loop executes as long as expr 2 true, executing expr3 each iteration.
    • while: while (expr) statements;
      Executes statements while the expression is true.
    • do...while: do { statements; } while (expr);
      Similar to while loops except that the condition is checked after the body of the loop, meaning that the body will always be executed at least once.
    • continue: continue [int arg];
      Skips the rest of the body of the loop for the current iteration and continue execution at the beginning of the next iteration. The optional arg tells it how many levels of loops it should skip to the end of (useful when using nested loops).
    • break: break [int arg];
      Ends the execution of the current loop. The optional arg tells it how many levels of loops it should break out of.
    • foreach: foreach (array_expression as [$key =>] $value) statements; 
      Loops over the array given by array_expression. On each iteration, the value of the current element is assigned to $value and the internal array pointer is advanced by one. If specifiec, the current element's key will be assigned to $key each iteration.

    Examples:
    for ($j = 0; $j < 10; $j++) {
       echo "Value number $j is {$value[$j]]}";
    }

    while ($b < $a) {
       echo "b is less than a.";
       $b++;
    }

    $i = 10;
    do {
       echo "This will execute at least once.";
    } while ($i < 10);

    for ($j = 0; $j < 10; $j++) {
       while($k < $j) {
         echo "j = $j, k = $k";
         if ($j == 1) break;
         if ($j % 2 == 1) continue 2;
         $k++;
      } echo "j is even or j equals 1.<br>";
    }

    foreach ($arr as $key => $value) {
       echo "Key: $key, Value: $value<br>\n";
    }

  9. Functions
    • Definition: Functions in PHP are defined with the following syntax:
      function funct($arg_1, $arg_2, ..., $arg_n) {
         echo "This is a function.";
         return $value;
      }
      Any PHP code, including other function and class definitions, may appear inside a function. Functions may also be defined within a conditional, but in that case the function's definition must be processed prior to its being called. PHP does not support function overloading but does support variable numbers of arguments as well as default arguments. Return types are not specified by function.
    • Arguments: By default, function arguments are passed by value so that if you change the value of the argument within the function, it does not get changed outside of the function. If you want the function to be able to modify its arguments, you must pass them by reference by prepending an ampersand to the argument name:
      function modify_arg(&$arg1, $arg2) {
         $arg1++;
       //$arg1 has now been modified
         $arg2++; //$arg2 has not
         return;
      }
    • Default Arguments: A function may define default values for scalar arguments. The default must be a constant expression and any defaults should be on the right side of any non-default arguments.
      function square($x = 5) {
         return x*x;
      }

      If this function is called with square();, it will return 25. Otherwise, if it is called with square($n); , it will return $n^2.
    • Variable length argument lists: The functions int func_num_args(), mixed func_get_arg(int arg_num), and array func_get_args() return the number of arguments passed to the function, the argument number arg_num as counted starting from zero, and an array of the function's argument list, respectively. To use a function with a variable length argument list, define the function with a void argument list: function var_arg_list() {...} and later call it with a variable number of arguments: $a = var_arg_list($b, "test", 3);. Within the function, use func_num_args, func_get_arg, and func_get_args to process and handle the arguments.
    • Return: Values are returned from the function with the return command: return $var;. You can not return multiple values, but that can be achieved by returning an array or object. Return immediately ends execution of the function and passes control back to the line from which it was called.
    • Variable Functions: PHP supports the concept of variable functions. That means that if a variable name has () appended to it, PHP will look for a function with the name of the value of the variable. Objects within a method can be called similarly.
      function test() {
         echo 'This is a test.';
      }
      $var = 'test';
      $var();
       //this calles test()
      $var = 'setRadius';
      $circle->$var(3);
       //this calls $circle->setRadius(3)

  10. Classes and OOP
    PHP supports OOP and classes. A class is a collection of variables and functions working with these variables. Classes are defined similarly to Java except that "->" is used instead of "." when referring to functions and elements of a class. You can NOT break up a class definition into multiple files or multiple PHP blocks.
    • Initializing vars: Only constant initializers for class variables are allowed (var $n = 1;). To initialize variables with non-constant values, you must use the constructor.
    • Encapsulation: PHP5 supports private and protected variables and methods. Prior to PHP5 however, everything is public and must be declared with either the var orfunction keywords.
    • Inheritence: PHP allows classes to be extended (see right) with the extendskeyword. The child class takes all the variables and functions from the parent class and can extend that class by adding additional variables and adding or overriding functions. If class B extends class A, then A or B can be used anywhere an A is expected, but only B can be used where a B is expected because it contains additional information/methods not found in A.
    • Abstract classes: Abstract classes are allowed in PHP5 but not before. Abstract classes create a template for other classes to extend and use. Instances can not be created of abstract classes but they are very useful when working with several objects that share many characteristics. For instance, when creating a database of people, one could define the abstract class "Person", which would contain basic attributes and functions common to all people in the database. Then child classes such as "SinglePerson", "MarriedCouple", or "Athlete" could be created by extending "Person" and adding appropriate variables and functions. The database could then be told to expect every entry to be an object of type "Person" and thus any of the child classes would be a valid entry.
    • Parent: The parent keyword allows you to call methods from the parent of the current class: parent::method_name(); (see right).
    • Constructors: Constructors are fuctions that are automatically called when you create a new instance of a class. They can be used for initialization purposes. A function is a constructor when it has the same name as the class it is defined in. When extending classes, if a new constructor is not defined, the constructor from the parent class is used (see right). When an object of type RectWithPerimeter is created, the constructor from Rectangle is called. If however, I were to add a function inRectWithPerimeter with the name RectWithPerimeter , then that function would be used as its constructor.
    • ::- PHP allows for referencing functions and variables in base classes or to functions in classes that do not yet have any instances with the :: operator. If you have a class A, and want to call its method test(); but do not yet have an instance of A, this can be done by: A::test();. Similarly, if class B extends A, functions in class B can refer to variables and functions in class A by: A::var and A::function($var);. It is recommended to use the parent keyword though to refer to members of the parent class.
    • Comparing Objects: Objects can, like arrays, be compared using the ==, !=, === (identical), and !== (not identical) operators. Two objects are equal if they have the same attributes and values and are instances of the same class.

    Example Class:
    class Rectangle {//Define variables width and height
       var $width, $height;
    //Constructor
       function Rectangle($width = 0, $height = 0) {
         $this->width = $width;
         $this->height = $height;
       }
    //functions
       function setWidth($width) {
         $this->width = $width;
       }
       function setHeight($height) {
         $this->height = $height;
       }
       function getArea() {
         return $this->width * $this->height;
       }
    }
    $arect = new Rectangle();
     //create a new Rectangle with dimensions 0x0. 
    $arect->setWidth(4);
    $arect->setHeight(6);
    echo $arect->getArea();

      -> 24
    $rect2 = new Rectangle(7,3); //new Rectangle with dimensions 7x3.

    Extended Class:
    class RectWithPerimeter extends Rectangle {//add new functions
       function getPerimeter() {
         return 2*$this->height + 2*$this->width;
       }
       function setDims($width, $height) {
    //use the parent keyword to call methods from Rectangle 
         parent::setWidth($width);
         parent::setHeight($height);
       }
    }
    $arect = new RectWithPerimeter(6,5);
     //Uses the constructor from Rectangle because no new constructor is provided to override it.
    echo $arect->getArea(); //Uses the getArea function from Rectangle and prints 30.
    echo $arect->getPerimeter(); //Uses getPerimeter from RectWithPerimeter and prints 22.
    $arect->setDims(4,9); //Use setDims to change the dimensions.

  11. File I/O
    PHP allows for reading/writing to files on the server that have correct permissions.
    • Opening Files: resource fopen(string filename, string mode): 
      fopen can be used to open local files or if enabled, remote files using http:// or ftp://. It binds a named resource to a stream that can then be used to read/write data. Possible modes include:
      • 'r': Open for reading.
      • 'w': Open for writing. Any existing data will be overwritten.
      • 'a': Open for writing. New data will be appended to existing data.
      • 'x': Create a new file and open for writing. If the file exists, fopen will fail and return FALSE.
      • 'b': Use this flag when working with binary files (e.g. 'rb').
    • Checking Files: PHP supports several methods of checking if a file exists and checking its properties:
      • bool is_dir(string filename): returns TRUE if the filename exists and is a directory.
      • bool is_file(string filename): returns TRUE if the filename exists and is a regular file.
      • bool is_readable(string filename): returns TRUE if the filename exists and is readable.
      • bool is_writable(string filename): returns TRUE if the filename exists and is writable.
    • File Operations: PHP also supports file operations such as copying and deleting files.
      • bool copy(string source, string dest): Copies the file source to dest. Returns TRUE if successful.
      • bool mkdir(string pathname, int mode): Makes a directory pathname with permissions mode (e.g. mkdir('new_dir', 0700);)
      • bool rename(string oldname, string newname): Renames a file
      • bool symlink(string target, string link): Creates a symbolic link to the existing target with name link.
      • bool unlink(String filename): Deletes filename.
    • Reading Files: Files can be read by several methods.
      • string fgets(resource handle [,int length]): Reads a line of up to a specified number of bytes from the file pointed to by handle into a string. It will read until it encounters a newline, EOF, or the specified length is reached (default is 1024 bytes). Handle is the handle created when the file was opened for reading with fopen.
      • string fread(resource handle, int length): Reads up to length bytes from the file pointed to by handle into a string. Can be used with binary files. Reading stops when length bytes have been read or EOF is reached.
      • int readfile(string filename): Reads a file and writes it to the output buffer. Returns the number of bytes read from the file.
      • string file_get_contents(string filename): Reads an entire file and returns it as a string.
      • array file(string filename): Reads an entire file and returns it as an array. Each element of the array corresponds to a line in the file, with the newline still attached.
    • EOF: bool feof(resource handle) can be used to check for end of file. while (! feof($handle)) { do_something }
    • Writing to files: Files that have been opened for writing with fopen can be written to by several methods.
      • int fwrite(resource handle, string string [,int length]): Writes the contents of string to the file stream pointed to by handle. Handle is the handle created when the file was opened for writing or appending with fopen. Writing stops after length bytes or the end of string is reached. Returns the number of bytes written or FALSE on error.
      • int file_put_contents(string filename, string data [,int flag]): Writes the string data to the file. If flag is set to FILE_APPEND, the file will be appended instead of overwritten.
    • Concurrency: File locking is available through the flock method. bool flock(resource handle, int operation), where operation can be LOCK_SH to acquire a shared lock (reader), LOCK_EX to acquire an exclusive lock (writer), LOCK_UN to release a lock, or LOCK_NB if you don't want flock to block while locking (or 1, 2, 3, or 4 respectively). Alternatively, you can write your own semaphors.
    • Serializing Objects: An object can be serialized with the method string serialize(mixed value). This will return a string representation of the object that can be stored anywhere (e.g. in a file for instance) and later reconstructed into the object with unserialize. mixed unserialize(string str) can then take a string representing a serialized object and reconstruct the object. If the object is an instance of a class, that class must be defined in the PHP page that unserializes the object (i.e. if you have an object of type A on page1.php, serialize it, write it to a file, and on page2.php you read it back in from the file, then class A must be defined on page2.php to unserialize the object. An easy solution is to put the definition of class A in a file to be included in both page1.php and page2.php). Arrays can be serialized as well.
    • Sockets: A socket can be opened with resource fsockopen (string target, int port [,int errno [,string errstr [,float timeout]]]). It returns a resource that can then be used with methods such as fgets, fwrite, feof, and fclose. Sockets are closed with fclose. If specified, errno and errstr will return the error number and details if an error occurs. Example: $s = fsockopen("www.example.com", 80, $errno, $errstr)
    Examples:
    $file = fopen("data/teams.txt","r");
    while (!feof($file)) {
       $team = fgets($file);
       echo $team;
    }
    fclose($file);

    $imgf = fopen("../img/football.jpg","rb");
    $image = "";
    while (!feof($imgf)) {
    $image .= fread($imgf,1024);
    }
    fclose($imgf);

    $player = serialize(new Player("J.J. Redick", "Duke", 4));
    $file = fopen("data/players.txt", "a");
    if (flock($fp, LOCK_EX)) {
       fwrite($file, $player);
       flock($file, LOCK_UN);
    } else echo "Couldn't lock the file!";
    fclose($file);

    $html = file_get_contents('http://www.example.com/');

  12. PHP and HTML Forms (User Input)
    When a form is submitted to a PHP script, the information from that form is automatically available to the script via several methods. First, you will want to set a form's action="script.php" and choose which method to use, "get" or "post". Get appends the arguments to the URL, while Post does not. PHP can then access the information from the form by the arrays $_GET and$_POST, depending on which method you used. The syntax is $var = $_POST['element_name'];, where element_name is the name assigned to a particular form element in the HTML code. If you do not care which method the form used, you can use the $_REQUEST array, which contains the contents of $_GET, $_POST, and $_COOKIE. 

    bool isset(mixed var): isset can be used to check whether a form has been submitted. It can also be used on any variable, returning TRUE if the variable exists. if (isset($_POST['name'])) ... 

    Image Submit variables: When using an image to submit a form instead of a standard submit button (<input type="image" src="image.gif" name="image_submit">), the form will be transmitted to the server with two additional variables, sub_x and sub_y. These contain the coordinates of the user click within the image. 

    Reading into arrays: By using [] or [key] within the name of the form element in the HTML, you can read the form information into arrays, i.e. $_POST['personal']['name'] or $_POST['beer'][0]. See the example to the right. If I had used personal[] for both Name and E-mail, then those values could be accessed by $_POST['personal'][0] and $_POST['personal'][1] respectively.

    Examples:
    < form action="script.php" method="post">
    Name: <input type="text" name="name"><br>
    E-mail: <input type="text" name="email"><br>
    </form>

    script.php:
    <?phpecho "Your name is " . $_POST['name'];
    $email = $_POST['email'];
    echo '<a href="mailto:' . $email . '">Send e-mail</a>
    ?>

    A more complex example:
    <?php
    if (isset($_POST['is_submitted']) && $_POST['is_submitted'] == 'submitted') {
    print_r($_POST);
    echo '<a href="'. $_SERVER['PHP_SELF'] .'">Try again</a>';
    } else {
    ?>
    <form action="<?php 
    echo $_SERVER['PHP_SELF']; ?>" method="post">
    Name: <input type="text" name="personal[name]"><br>
    E-mail: <input type="text" name="personal[email]"><br>
    Beer:<br>
    <select multiple name="beer[]"> <option value="warthog">Warthog
    <option value="guinness">Guinness
    <option value="stuttgarter">Stuttgarter Schwabenbräu
    </select><br>
    <input type="hidden" name="is_submitted" value="submitted">
    <input type="submit" name="submit" value="submit me!">
    </form>
    <?php
    }?>

  13. Guess My Number
    Here is the code for Guess My Number in PHP, a program that generates a random number between 1 and 100 and asks the user to guess it. It will tell the user if the number is higher or lower after each guess and keep track of the number of guesses. This is just one way to write it in PHP.

    <title>Guess My Number (PHP)</title>
    <h1>Guess My Number (PHP)</h1>
    <?php
    $b = $_POST['b'];
    $x = $_POST['x'];
    $out = $_POST['out'];
    ?>
    <form action="gmn.php" method="post">
    Guess My Number (1-100): <input type="text" name="number" size=3>
    <br>
    <input type="submit" value="Guess">
    <?php
    if ($b == 0) {
       $x = mt_rand(1,100);
       $out = "";
    }
    ?>
    <input type="hidden" name="b" value=<?php echo ++$b;?>>
    <input type="hidden" name="x" value=<?php echo $x;?>>
    <?php
    if ($b > 1) {
       $a = $_POST['number'];
       if ($a != $x) $out .= ($a < $x) ? "Higher than $a.<br>" : "Lower than $a.<br>";
    ?>
    <input type="hidden" name="out" value="<?php echo $out;?>">
    </form>
    <?php
       echo $out;
       if ($a == $x) {
          echo "$a is correct!  " . ($b-1) . " tries.";
       }
    }
    ?>
    <br><br>
    <a href="gmn.php">Play Again</a>

  14. PHP reference
    PHP.net: includes an introductory tutorial and a full manual.