Saturday, January 31

How to use PHP-APD( Advanced PHP debugger ) in your scripts

1. As the first line of your PHP script, call the apd_set_pprof_trace() function to start the trace:

<?php
apd_set_pprof_trace();
?>

You can insert the line anywhere in your script, but if you do not start tracing at the beginning of your script you discard profile data that might otherwise lead you to a performance bottleneck.

2. Now run your script. The dump output will be written to apd.dumpdir/pprof_pid.ext.

Tip
If you're running the CGI version of PHP, you will need to add the '-e' flag to enable extended information for apd to work properly. For example: php -e -f script.php

3. To display formatted profile data, issue the pprofp command with the sort and display options of your choice. The formatted output will look something like:

bash-2.05b$ pprofp -R /tmp/pprof.22141.0

Trace for /home/dan/testapd.php
Total Elapsed Time = 0.00
Total System Time  = 0.00
Total User Time    = 0.00


Real         User        System             secs/    cumm
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name
--------------------------------------------------------------------------------------
100.0 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0000   0.0009            0 main
56.9 0.00 0.00  0.00 0.00  0.00 0.00     1  0.0005   0.0005            0 apd_set_pprof_trace
28.0 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 preg_replace
14.3 0.00 0.00  0.00 0.00  0.00 0.00    10  0.0000   0.0000            0 str_replace
The -R option used in this example sorts the profile table by the amount of real time the script spent executing a given function. The "cumm call" column reveals how many times each function was called, and the "s/call" column reveals how many seconds each call to the function required, on average.

4. To generate a calltree file that you can import into the KCacheGrind profile analysis application, issue the pprof2calltree comand.

reference: http://php.net/manual/en/apd.examples.usage.php

Files to a ZIP archive PHP

1. If you want to add files to a ZIP archive but you don't know if the ZiP file exists or not, you MUST check: this changes the way you open it !.
2. you can not append multiple flags, can use only one (or none).

If the zip does not exists, open it with:
$ziph->open($archiveFile, ZIPARCHIVE::CM_PKWARE_IMPLODE)
(or a different compression method)

If the zip already exists, open it with:
$ziph->open($archiveFile)
or
$ziph->open($archiveFile, ZIPARCHIVE::CHECKCONS)

Example: make backup files every hour and ZIP them all in a daily ZIP archive, so you want to get only one ZIP per day, each ZIP containing 24 files:

<?php
  function archivebackup($archiveFile, $file, &$errMsg)
  {
    $ziph = new ZipArchive();
    if(file_exists($archiveFile))
    {
      if($ziph->open($archiveFile, ZIPARCHIVE::CHECKCONS) !== TRUE)
      {
        $errMsg = "Unable to Open $archiveFile";
        return 1;
      }
    }
    else
    {
      if($ziph->open($archiveFile, ZIPARCHIVE::CM_PKWARE_IMPLODE) !== TRUE)
      {
        $errMsg = "Could not Create $archiveFile";
        return 1;
      }
    }
    if(!$ziph->addFile($file))
    {
      $errMsg = "error archiving $file in $archiveFile";
      return 2;
    }
    $ziph->close();
    
    return 0;
  }
?>

Zip Usage Example PHP

<?php

$zip = zip_open("/tmp/test2.zip");

if ($zip) {
    while ($zip_entry = zip_read($zip)) {
        echo "Name:               " . zip_entry_name($zip_entry) . "\n";
        echo "Actual Filesize:    " . zip_entry_filesize($zip_entry) . "\n";
        echo "Compressed Size:    " . zip_entry_compressedsize($zip_entry) . "\n";
        echo "Compression Method: " . zip_entry_compressionmethod($zip_entry) . "\n";

        if (zip_entry_open($zip, $zip_entry, "r")) {
            echo "File Contents:\n";
            $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
            echo "$buf\n";

            zip_entry_close($zip_entry);
        }
        echo "\n";

    }

    zip_close($zip);

}
?>

Dump the archive details and listing PHP

<?php
$za = new ZipArchive();

$za->open('test_with_comment.zip');
print_r($za);
var_dump($za);
echo "numFiles: " . $za->numFiles . "\n";
echo "status: " . $za->status  . "\n";
echo "statusSys: " . $za->statusSys . "\n";
echo "filename: " . $za->filename . "\n";
echo "comment: " . $za->comment . "\n";

for ($i=0; $i<$za->numFiles;$i++) {
    echo "index: $i\n";
    print_r($za->statIndex($i));
}
echo "numFile:" . $za->numFiles . "\n";
?>

Create a Zip archive using PHP

<?php

$zip = new ZipArchive();
$filename = "./test112.zip";

if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
    exit("cannot open <$filename>\n");
}

$zip->addFromString("testfilephp.txt" . time(), "#1 This is a test string added as testfilephp.txt.\n");
$zip->addFromString("testfilephp2.txt" . time(), "#2 This is a test string added as testfilephp2.txt.\n");
$zip->addFile($thisdir . "/too.php","/testfromfile.php");
echo "numfiles: " . $zip->numFiles . "\n";
echo "status:" . $zip->status . "\n";
$zip->close();
?>

Friday, January 30

With HTML5 file uploads with Ajax and jQuery.

The HTML:
    <form enctype="multipart/form-data">
        <input name="file" type="file" />
        <input type="button" value="Upload" />
    </form>
    <progress></progress>
 
Do some validation if you want. For example, in the onChange event of the file:

    jQuery(':file').change(function(){
        var file = this.files[0];
        var name = file.name;
        var size = file.size;
        var type = file.type;
        //Your validation
    });

file validations (name, size, and MIME-type) or handle the progress event with the HTML5 progress tag (or a div).


Ajax submit with the button's click:

    jQuery(':button').click(function(){
        var formData = new FormData(jQuery('form')[0]);
        jQuery.ajax({
            url: 'upload.php',  //Server script to process data
            type: 'POST',
            xhr: function() {  // Custom XMLHttpRequest
                var myXhr = jQuery.ajaxSettings.xhr();
                if(myXhr.upload){ // Check if upload property exists
                    myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // For handling the progress of the upload
                }
                return myXhr;
            },
            //Ajax events
            beforeSend: beforeSendHandler,
            success: completeHandler,
            error: errorHandler,
            // Form data
            data: formData,
            //Options to tell jQuery not to process data or worry about content-type.
            cache: false,
            contentType: false,
            processData: false
        });
    });
 
 
To handle the progress:

    function progressHandlingFunction(e){
        if(e.lengthComputable){
            jQuery('progress').attr({value:e.loaded,max:e.total});
        }
    }

Thursday, January 29

PHP error handling and exception handling

Below is an example of defined an error handling function which logs the information into a file (using an XML format), and e-mails the developer if a critical error in the logic happens.

Example:


<?php
// we will do our own error handling
error_reporting(0);

// user defined error handling function
function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars) 
{
    // timestamp for the error entry
    $dt = date("Y-m-d H:i:s (T)");

    // define an assoc array of error string

    // in reality the only entries we should
    // consider are E_WARNING, E_NOTICE, E_USER_ERROR,
    // E_USER_WARNING and E_USER_NOTICE
    $errortype = array (
                E_ERROR              => 'Error',
                E_WARNING            => 'Warning',
                E_PARSE              => 'Parsing Error',
                E_NOTICE             => 'Notice',
                E_CORE_ERROR         => 'Core Error',
                E_CORE_WARNING       => 'Core Warning',
                E_COMPILE_ERROR      => 'Compile Error',
                E_COMPILE_WARNING    => 'Compile Warning',
                E_USER_ERROR         => 'User Error',
                E_USER_WARNING       => 'User Warning',
                E_USER_NOTICE        => 'User Notice',
                E_STRICT             => 'Runtime Notice',
                E_RECOVERABLE_ERROR  => 'Catchable Fatal Error'
                );
    // set of errors for which a var trace will be saved
    $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
    
    $err = "<errorentry>\n";
    $err .= "\t<datetime>" . $dt . "</datetime>\n";
    $err .= "\t<errornum>" . $errno . "</errornum>\n";
    $err .= "\t<errortype>" . $errortype[$errno] . "</errortype>\n";
    $err .= "\t<errormsg>" . $errmsg . "</errormsg>\n";
    $err .= "\t<scriptname>" . $filename . "</scriptname>\n";
    $err .= "\t<scriptlinenum>" . $linenum . "</scriptlinenum>\n";

    if (in_array($errno, $user_errors)) {

        $err .= "\t<vartrace>" . wddx_serialize_value($vars, "Variables") . "</vartrace>\n";
    }
    $err .= "</errorentry>\n\n";
    
    // for testing
    // echo $err;

    // save to the error log, and e-mail me if there is a critical user error

    error_log($err, 3, "/usr/local/php5/error.log");
    if ($errno == E_USER_ERROR) {
        mail("admin@domain.com", "Critical User Error", $err);
    }
}


function distance($vect1, $vect2) 
{
    if (!is_array($vect1) || !is_array($vect2)) {
        trigger_error("Incorrect parameters, arrays expected", E_USER_ERROR);
        return NULL;
    }

    if (count($vect1) != count($vect2)) {

        trigger_error("Vectors need to be of the same size", E_USER_ERROR);
        return NULL;
    }

    for ($i=0; $i<count($vect1); $i++) {

        $c1 = $vect1[$i]; $c2 = $vect2[$i];
        $d = 0.0;
        if (!is_numeric($c1)) {
            trigger_error("Coordinate $i in vector 1 is not a number, using zero", 
                            E_USER_WARNING);
            $c1 = 0.0;
        }
        if (!is_numeric($c2)) {
            trigger_error("Coordinate $i in vector 2 is not a number, using zero", 
                            E_USER_WARNING);
            $c2 = 0.0;
        }
        $d += $c2*$c2 - $c1*$c1;
    }
    return sqrt($d);
}

$old_error_handler = set_error_handler("userErrorHandler");

// undefined constant, generates a warning
$t = I_AM_NOT_DEFINED;

// define some "vectors"
$a = array(2, 3, "foo");
$b = array(5.5, 4.3, -1.6);
$c = array(1, -3);

// generate a user error
$t1 = distance($c, $b) . "\n";

// generate another user error
$t2 = distance($b, "i am not an array") . "\n";

// generate a warning
$t3 = distance($a, $b) . "\n";

?>

Tuesday, January 27

mySql using Prepared Statement with php

test.html

    <form action="test.php" method="POST">
        <input name="test" type="text">
        <input name="submit" type="submit" value="Submit">
    </form>
 
test.php

<?php
    if (isset($_POST['submit'])) {
    
    $mysqli = new mysqli('localhost', 'user', 'password', 'mytestdb');
    
    /* check connection */
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }
    
    $stmt = $mysqli->prepare("INSERT INTO table_name VALUES (?)");
    $stmt->bind_param('s', $test);   // bind $test to the parameter
    
    // escape the POST data for added protection
    $test = isset($_POST['test']) ? $mysqli->real_escape_string($_POST['test']) : '';
    
    /* execute prepared statement */
    $stmt->execute();
    
    printf("%d Row inserted.\n", $stmt->affected_rows);
    
    /* close statement and connection */
    $stmt->close();
    
    /* close connection */
    $mysqli->close();
    }
?>

real_escape_string() is superfluous. The whole point of using prepared statements is to avoid having to escape the values manually.

Prevent SQL-injection in PHP

The SQL statements that are sent to and parsed by the database server separately from any parameters. This way it is impossible for an attacker to inject malicious SQL.

You basically have two options to achieve this:

1. prepared statements (PDO):

$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');

$stmt->execute(array('name' => $name));

foreach ($stmt as $row) {
    // do something with $row
}

2. parameterized queries (MySQLi):

$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);

$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // do something with $row
}

Correctly setting up the connection

Note that when using PDO to access a MySQL database real prepared statements are not used by default. To fix this you have to disable the emulation of prepared statements. An example of creating a connection using PDO is:

$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');

$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

In the above example the error mode isn't strictly necessary, but it is advised to add it. This way the script will not stop with a Fatal Error when something goes wrong. And it gives the developer the chance to catch any error(s) which are thrown as PDOExceptions.

What is mandatory however is the first setAttribute() line, which tells PDO to disable emulated prepared statements and use real prepared statements. This makes sure the statement and the values aren't parsed by PHP before sending it to the MySQL server (giving a possible attacker no chance to inject malicious SQL).

Although you can set the charset in the options of the constructor, it's important to note that 'older' versions of PHP (< 5.3.6) silently ignored the charset parameter in the DSN.

Explanation

What happens is that the SQL statement you pass to prepare is parsed and compiled by the database server. By specifying parameters (either a ? or a named parameter like :name in the example above) you tell the database engine where you want to filter on. Then when you call execute, the prepared statement is combined with the parameter values you specify.

The important thing here is that the parameter values are combined with the compiled statement, not an SQL string. SQL injection works by tricking the script into including malicious strings when it creates SQL to send to the database. So by sending the actual SQL separately from the parameters, you limit the risk of ending up with something you didn't intend. Any parameters you send when using a prepared statement will just be treated as strings (although the database engine may do some optimization so parameters may end up as numbers too, of course). In the example above, if the $name variable contains 'Sarah'; DELETE FROM employees the result would simply be a search for the string "'Sarah'; DELETE FROM employees", and you will not end up with an empty table.

Another benefit with using prepared statements is that if you execute the same statement many times in the same session it will only be parsed and compiled once, giving you some speed gains.

Oh, and since you asked about how to do it for an insert, here's an example (using PDO):

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));


Source: http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php?rq=1

jQuery ajax, to send JSON instead of QueryString

You need to use JSON.stringify to first serialize your object to JSON, and then specify the content-type so your server understands it's JSON. This should do the trick:

$.ajax({
    url: url,
    type: "POST",
    data: JSON.stringify(data),
    processData: false,
    contentType: "application/json; charset=UTF-8",
    complete: callback
});

Note that not all browsers support the JSON object, and although jQuery has .parseJSON, it has no stringifier included; you'll need another polyfill library.

Setting processData to false isn't necessary since JSON.stringify already returns a string.

Pass array to ajax request in $.ajax()

info = [];
info[0] = 'hi';
info[1] = 'hello';


$.ajax({
   type: "POST",
   data: {info:info},
   url: "index.php",
   success: function(msg){
     $('.answer').html(msg);
   }
});

sprintf php function is about 10x faster.

Use sprintf instead of variables contained in double quotes, it’s about 10x faster.

<?php
$num = 5;
$location = 'tree';

$format = 'There are %d monkeys in the %s';
echo sprintf($format, $num, $location);
?>

Source: http://php.net/manual/en/function.sprintf.php

Methods in derived classes run faster than ones defined in the base class.

Example:

<?php

class Foo
{
    public function printItem($string)
    {
        echo 'Foo: ' . $string . PHP_EOL;
    }
    
    public function printPHP()
    {
        echo 'PHP is great.' . PHP_EOL;
    }
}

class Bar extends Foo
{
    public function printItem($string)
    {
        echo 'Bar: ' . $string . PHP_EOL;
    }
}

//Function call is slower then derived class
$foo = new Foo();
$foo->printItem('baz'); // Output: 'Foo: baz'
$foo->printPHP();       // Output: 'PHP is great' 


//Function call is faster then the base class
$bar = new Bar();
$bar->printItem('baz'); // Output: 'Bar: baz'
$bar->printPHP();       // Output: 'PHP is great'

?>

MySql Database Connectivity with Reduced Number of Hits

Try to reduce the number of hits to the database. Make queries aggregate so that you call the database less number of times.
For example:

<?php
  $connection=mysqli_connect("localhost","username","password","db_name");
  
  if (mysqli_connect_errno())
  {
    echo "Failed to connect to MySQL" ;
mysqli_connect_error(); 
  }

  function insertValue( $val ){
    mysqli_query($connection,"INSERT INTO table_name (integerValue) VALUES ( $value )");
  }
  
  for( $i =0; $i<99; $i++){
    //  Calling function to execute query one by one 
    insertValue( $i );
  }
  // Closing the connection as best practice
  mysqli_close($connection);

?>

The script above is much slower.
So, script below is the best solution to run fast:

<?php
  $connection=mysqli_connect("localhost","username","password","db_name");
  if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL" ;
  mysqli_connect_error(); 
  }
   
  function insertValues( $val ){
     // Creating query for inserting complete array in single execution.
    $query= " INSERT INTO table_name(integerValue) VALUES .implode(',', $value)";      
    mysqli_query($connection, $query);
  }
  
  $data_array = array();
  for( $i =0; $i<99; $i++){
    // Creating an array of data to be inserted.
    $data_array[ ]  =   '(" ' . $i. '")' ;
  }
  // Inserting the data in a single call
  insertValues( $data_array );
  // Closing the connection as a best practice
  mysqli_close($connection);

?>

Pass Reference to Function in PHP

Pass reference to the function if it does not affect your logic. A function manipulating the reference is faster than those manipulating the value been passed as here one more copy of the value is getting created. Especially it adds overhead when the value passed by you is a big array.

For example, let us create a function in two different way to increment by 1, each element of an array having values 0 to 99.


<?php
  // passing by reference
  function  computeValue( &$param ){
  // Something goes here
  foreach( $param as $k => $value){
   $param[$k] = $value + 1;
  }
  }
  $x = array();
  for( $i =0; $i<99; $i++){
    $x[$i] = $i;
  }
  computeValue( $x);
  
  // array with 100 elements each incremented by 1
  print_r( $x );

?> 

The function above works faster than the function below although both will produce the same result ( increment each element of the array by 1. )

<?php
  // passing by value
    function  computeValue( $param ){
      // Something goes here
      foreach( $param as $k => $value){
      $param[$k] = $value + 1;
      }
      
      return $param;
    }
    $x = array();
    for( $i =0; $i<99; $i++){
      $x[$i] = $i;
    }
// array with 100 elements each incremented by 1
    print_r(computeValue( $x));
    
  ?>

jQuery multiple class selector

If You have two classes a and b.

<element class="a b">

If you want an intersection, just write the selectors together without spaces in between. So for an element that has an ID of a with classes b and c, you would write:

jQuery('.a.b')

jQuery('#a.b.c')

        OR
You can do this using the filter function:

jQuery(".a").filter(".b")

    -NOTE: This one will be a little bit slower, because it will build a list of objects with class "a" first, then remove all but those that have class "b", whereas mine does this in one step. But otherwise, no difference.

$(this) selector and children?

Having a layout similar to this

<div id="..."><img src="..."></div>

The jQuery constructor accepts a 2nd parameter called context which can be used to override the context of the selection.

jQuery("img", this);
Which is the same as using .find() like this:

jQuery(this).find("img");
If the imgs you desire are only direct descendants of the clicked element, you can also use .children():

jQuery(this).children("img");


            OR
         
You could also use

jQuery(this).find('img');
which would return all imgs that are descendants of the div

If you need to get the first img that's down exactly one level, you can do

jQuery(this).children("img:first")

Custom Slider using jQuery

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Custom Slider demo</title>
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>

<div class="slides">

    <ul>
        <li><img src="image-1.jpg" alt="" /></li>
        <li><img src="image-2.jpg" alt="" /></li>
        <li><img src="image-3.jpg" alt="" /></li>
        <li><img src="image-4.jpg" alt="" /></li>
        <li><img src="image-5.jpg" alt="" /></li>
    </ul>
</div>

<script>

jQuery(document).ready(function(){
jQuery(".slides ul > li:gt(0)").hide();
setInterval(function() {
 jQuery('.slides ul > li:first')
   .fadeOut(1000)
   .next()
   .fadeIn(1000)
   .end()
   .appendTo('.slides ul');
},  3000);
});
</script>

</body>

</html>