Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

Friday, April 4, 2014

PHP - Steps to increase the efficiency of PHP code


If you're a developer, it is necessary for you to improve your script in the development process itself early. Following the best practices while coding your PHP script is a good starting point to write PHP code optimization as well.

This tutorial provides few tips to optimize PHP code from a developer point of view.

1. Use Native PHP Functions
As much as possible, try to use the functions of the original PHP instead of writing your own functions to achieve your goal. For example, you can use range (b, k) to get of alphabets ranging from b to k in sequence, if necessary only once in the script instead of the Declaration of an array with the values ​​in the function and return the call.
2. Use Single Quotes
Using single quotes ( ‘ ‘ ) is faster than using double quotes( ” ” ) if you are going to keep only the string inside it avoiding any variables. Double quotes checks for the presence of variable and adds little bit of overhead.
3. Use = = = in your conditions
Use “= = =” instead of “= =”, as the former strictly checks for a closed range which makes it faster.
4. Use Appropriate Str Functions

str_replace is faster than preg_replace, but strtr is faster than str_replace by a factor of 4.
5. Calculate Only Once
Account and set the value to a variable if it is getting used many times instead of calculating it over and over again where it is used.
For example, the following will degrade the performance.
for( $i=0; i< count($arr); $i++){
  echo count($arr);
}
The script below will perform much better.
$len = count($arr);
for( $i=0; i< $len; $i++){
  echo $len;
}
6. Pass Reference to Function
Pass the reference to function if it does not affect your logic. The function of manipulating the signal faster than those that have been passed to manipulate the value as here is getting more and create a single copy of the value. Especially as it adds overhead when the value that was passed by you is a large group.
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.
 
  // 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. )
 
   // 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));
    
7. Create Classes Only When its Required
Don’t create classes and method until and unless its really needed, used and reused as well.
8. Disable Debugging Messages
File operations are expensive. So, if you have written lot of custom functions to log errors and warning during your development process, make sure you remove them before you push the code to production.
9. Use Caching Techniques
Use cache to reduce the load of database operations as well as the script compilation. We can use memcache for the reducing database load and APC for opcode caching and intermediate code optimization.
10. Close the Connection
Get into the habit to unset the variables and close database connection in your PHP code. It saves memory.
11. Reduce Number of Hits to DB
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:
 
  $con=mysqli_connect("localhost","username","somepassword","anydb");
  
  if (mysqli_connect_errno())
  {
    echo "Failed to connect to MySQL" ;
 mysqli_connect_error(); 
  }

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


The script above is much slower than the script below:
 
  $con=mysqli_connect("localhost","username","somepassword","anydb");
  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 tableX(someInteger) VALUES .implode(',', $val)";      
    mysqli_query($con, $query);
  }
  
  $data = array();
  for( $i =0; $i<99; $i++){
    // Creating an array of data to be inserted.
    $data[ ]  =   '(" ' . $i. '")' ;
  }
  // Inserting the data in a single call
  insertValues( $data );
  // Closing the connection as a best practice
  mysqli_close($con);

 
12. Frequently Used Switch Cases
Keep most frequently used switch cases on the top.
13. Use Methods in Derived Classes
Methods in derived classes are faster than base classes. For example, let there be a function in both base class and derived class for performing task1. It is named as “forTask1″ in base class and “forTask1again” in derived class, so that they will not override.

Call to the function “forTask1again( )” which is in derived class will work faster than call to the function “forTask1( )” as it is from base class.
 
  class someBaseClass
  {
   public function forTask1($string)
   {
    // perform task 1
   }
   public function forTask2( )
   {
    // perform task 2
   }
  }
  
  class derivedClass extends someBaseClass
  {
   public function forTask1again($string)
   {
    //perform task 1 same as the function in base class.
   }
   public function forTask3($string)
   {
    //perform task 3
   }
  }
  //Instantiating the derived class below.
  $objDerivedClass = new derivedClass( ); 
  
  // The call below works slow for task1 as it is from base class.
  $resultTask1 = $objDerivedClass->forTask1( );
  
  // The call below works faster for task1 as 
  // it is from derived class.
  $sameResultTask1 = $objDerivedClass->forTask1again();
 
14. Use JSON
Use JSON instead of XML while working with web services as there are native php function like json_encode( ) and json_decode( ) which are very fast. If you are bound to have XML form of data, then use regular expression to parse it instead of DOM manipulation.
15. Use isset
Use isset( ) where ever possible instead of using count( ), strlen( ), sizeof( ) to check whether the value returned is greater than 0.
For example, let us assume that you have a function which returns an array with values or a NULL array. Now you want to check whether the returned array is with values or not, then use the following:
if(isset($returnValue)){
  // do something here
}
In this case, use the above code block, instead of the following:
if(count($returnValue) > 0){
  // do something here
}

Thursday, April 3, 2014

PHP - prevent SQL injection in PHP

What is SQL injection ?

 Many web developers are unaware of how SQL queries can be tampered with, and assume that an SQL query is a trusted command. It means that SQL queries are able to circumvent access controls, thereby bypassing standard authentication and authorization checks, and sometimes SQL queries even may allow access to host operating system level commands.

 Direct SQL Command Injection is a technique where an attacker creates or alters existing SQL commands to expose hidden data, or to override valuable ones, or even to execute dangerous system level commands on the database host. This is accomplished by the application taking user input and combining it with static parameters to build an SQL query. SQL Injection flaws are introduced when software developers create dynamic database queries that include user supplied input.

To avoid SQL injection flaws is simple. Developers need to either: a) stop writing dynamic queries; and/or b) prevent user supplied input which contains malicious SQL from affecting the logic of the executed query. This article provides a set of simple techniques for preventing SQL Injection vulnerabilities by avoiding these two problems. These techniques can be used with practically any kind of programming language with any type of database. There are other types of databases, like XML databases, which can have similar problems (e.g., XPath and XQuery injection) and these techniques can be used to protect them as well.



Primary Defenses:

 #1: Use of Prepared Statements (Parameterized Queries)
 #2: Escaping all User Supplied Input

 Here will show simple example of unsafe query :
 $SQL = "SELECT * FROM members WHERE email = '$email' ";
The SQL this time has a WHERE clause added. The WHERE clause is used when you want to limit the results to only records that you need. After the word "WHERE", you type a column name from your database (email, in our case). You then have an equals sign, followed by the value you want to check. The value we want to check is coming from the variable called $email. This is surrounded with single quotes. When an email address is entered in the text box on our form, this value goes straight into the variable without any checks.

When you type that extra single quote on the end, that will be added to the SQL. This is then run on the database. Because it's a stray single quote, you'll get a syntax error. It's this syntax error that an attacker is looking for. Next, the attacker will try to add some SQL to yours. Try this. In the email address textbox, type the following. Type it exactly as it is, with the single quotes:
hi' OR 'x'='x
When you click the Submit button, you should find that there are no errors, and that the username, password and email address are printed out! The attacker is trying to find out whether or not the SQL can be manipulated. If the answer is yes, further attacks will be launched. Can the table and field names be guessed? Can a username and password be guessed? It's this kind of attack that you want to thwart. Try this last one. Enter the following into the email address box:
' OR ''='
Using defense method #1
Php introduce many extensions to communicate with your database . Use prepared statements and parameterized queries. These are 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.

 Using PDO:
$stmt = $pdo->prepare('SELECT * FROM Client WHERE name = :name');
$stmt->execute(array('name' => $name));
foreach ($stmt as $row) {
//row
}

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

$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 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).

Using Mysqli
$stmt = $dbConnection->prepare('SELECT * FROM ClientsWHERE name = ?');
$stmt->bind_param('s', $name);

$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // row

}
Using defense method #2
You've got two options - escaping the special characters in your unsafe_variable, or using a parameterized query. Both would protect you from SQL injection. The parameterized query is considered the better practice, but escaping characters in your variable will require fewer changes. We'll do the simpler string escaping one first.

$unsafe_variable = $_POST["user-input"];
$safe_variable = mysql_real_escape_string($unsafe_variable);

mysql_query("INSERT INTO table (column) VALUES ('" . $safe_variable . "')");
Good Luck