Tuesday, April 30, 2013

Select multiple checkboxes using Javascript and jQuery

Suppose, we have a form as shown below.



It has 3 buttons, when the "Select All" button is clicked, all the checkboxes are checked, while "Select None" button unchecks all the chekboxes. Now, we need to write two javascirpt functions which checks/unchecks all the checkboxes at once. Check out the code below.

<html>
<head>
<script type='text/javascript'>

function fselect_all()
{
 // IE 8 and others support querySelectorAll()
 var col = document.querySelectorAll("input[type=checkbox]");
 for(var i=0; i<col.length; i++ )
 {
   col[i].checked = true; // Check
 }
}

function fselect_none()
{
  // IE 8 and others support querySelectorAll()
 var col = document.querySelectorAll("input[type=checkbox]");
 for(var i=0; i<col.length; i++ )
 {
   col[i].checked = false; // Uncheck
 }
}
</script>
</head>
<body>

<form>
<table>
 <!-- Dynamic Generation of Table Items -->
<?php
  for( $i=1;$i<=10; $i++)
  {
?>
   <tr>
    <td>
      <input type='checkbox' name="sel[<?php echo $i;?>]">
      Item <?php echo $i;?> </td>
   </tr>
<?php 
  }
?> 
 <tr>
  <td>
    <input type='button' value='Select All' onclick='fselect_all()'>
    <input type='button' value='Select None' onclick='fselect_none()'>
    <input type='submit' value='Submit' name='btn_submit'>
  </td>
 </tr>
</table>
</form>
</body>
</html>


Some points to be noticed in the above piece of code ::
1. We are generating the checkboxes using a PHP for loop which generates the following table rows ..

 <tr><td><input type='checkbox' name="sel[1]">  Item 1 </td></tr>
 <tr><td><input type='checkbox' name="sel[2]">  Item 2 </td></tr>

  ...
2. In the fselect_all()  and fselect_none() functions, we are using querySelectoAll() method which is supported in all new browsers. IE8 onwards have support for it. This function takes CSS like selectors for selecting DOM nodes and returns all the matching node/elements as a collection it finds. Then we simply run a Javascript for() loop to iterate each checkbox item and then we set their "checked" property to true or false as needed.

The above task can be easily done using jQuery. Check the new fselect_all() and fselect_none() functions which use jQuery statements for checking/unchecking checkboxes.

function fselect_all()
{
  $("input[type=checkbox]").each(function(){ this.checked = true; });
}

function fselect_none()
{
  $("input[type=checkbox]").each(function(){ $(this).removeAttr('checked'); });
}


The statement " this.checked = true; " is a Javascript one, using the statement $(this).attr('checked',true); instead checks the checkboxes only once. This phenomenon can be seen on jsFiddle. Hence we better use the old Javascript statement for checking all checkboxes.

To add checked='checked' to a Checkbox, we can use jQuery's prop() method. And to remove the check, instead of using removeAttr('checked') we can use removeProp(' checked') method. Adding  checked='checked' using the prop() method may not appear in FireBug etc tools.

Now, we would submit the form and see how the inputs are captured at the server end. Check the PHP code below.

<?php
if( isset($_REQUEST['sel']) )
{
   /// Iterate the Items
   foreach( $_REQUEST['sel'] as $key => $val)
   {
     /// Get the ID
     $customer_id = $key;
    
     /// Do some SQL queries
     ...
   }

}

?>

Only selected items will be captured in the above array at the server side. In the PHP loop above, $val for all the array items would have a value of "on". When a checkbox is checked and submitted, server gets a value of "on" against the element's name unless a value is specified as shown below :

<input type='checkbox' name='sel[]' value='test 1'>

Friday, April 26, 2013

Submitting Forms with multiple textboxes having same name

Creation of table with dynamic textboxes has been shown here. In such scenarios, it is good to name the textbox elements as "row[]" or "text[]" which look like an array construction. When the form is submitted, all the textbox's values will be available to PHP in an array which would be very easy for further processing.

Suppose, all the textboxes have a name structure like "text[]" as shown in the example form below.

<!-- FORM STARTS -->
<form name='f' method='post'>

<!-- INPUT Elements -->
<input type='text' name='text[]' value='0'>
<input type='text' name='text[]' value='1'>
<input type='text' name='text[]' value='2'>
<input type='text' name='text[]' value='3'>

<input type='submit' name='btn_submit' value='Submit Me'>

</form>
<!-- FORM ENDS -->


When we submit the form above, PHP receives values of all the textbox elements in an array format in variable $_POST['text']. If we run the following PHP statement :

<?php
print_r( $_POST['text'] );
?>


the output would be :

Array
(
    [text] => Array
        (
            [0] => 0
            [1] => 1
            [2] => 2
            [3] => 3
        )
)


If we give different index with the element as shown below :

<input type='text' name='text[123]' value='0'>
<input type='text' name='text[125]' value='1'>
<input type='text' name='text[147]' value='2'>
<input type='text' name='text[189]' value='3'>


the PHP  statement print_r( $_POST['text'] ); would give the following output.

Array
(
    [text] => Array
        (
            [123] => 0
            [125] => 1
            [147] => 2
            [189] => 3
        )
)


Creation of such textboxes can be done with the following piece of PHP code.

<table>
<?php
 for($i=0; $i<10; $i++)
 {
?>
  <tr>
    <td>
      <input type='text' name='text_<?php echo $i;?>'>
    </td>
  </tr>
<?php
}
?>
</table>


This generates the following HTML code. Notice the element's name is a bit different.

<table>
  <tr>
    <td> <input type='text' name='text_0'> </td>
  </tr>
  <tr>
    <td> <input type='text' name='text_1'> </td>
  </tr>
  <tr>
    <td> <input type='text' name='text_2'> </td>
  </tr>
  <tr>
    <td> <input type='text' name='text_3'> </td>
  </tr>
</table>


The statement :

<input type='text' name='text[<?php echo $i;?>]'>

would generate input elements like this :

<input type='text' name='text[0]'>
<input type='text' name='text[1]'>


But we can still manage to collect the element's value, after the form is submitted, easily.

<?php
for($i=0; $i<10; $i++)
{
  $index = "text_" . $i;
  echo $_POST[$index] . ", ";
}
?>


Now, a question ... what if all the elements share a common name as shown in the HTML below?

<input type='text' name='text' value='0'>
<input type='text' name='text' value='1'>
<input type='text' name='text' value='2'>
<input type='text' name='text' value='3'>


Only the last element's value will be available to PHP i.e $_POST['text'] would collect only last element's value of "3".

Thursday, April 25, 2013

Creating Dynamic Table Rows and Columns In Javascript

Before we get into the solution, here I first discuss the problem we are going to solve through Javascirpt.

Problem : We have a HTML page which looks like this:

  



 



The coresponding HTML is also given below.

<html>
<body>
<table id="table"></table>
<input type='button' value='Add New' id='button' onclick='add_new()'>
</body>
</html>


Now when we click on "Add New" button, a new row is created and appended to the <table> element shown in the above HTML. If we repeat it couple of times, we would be generating a big dynamically generated table as shown in the picture below ...


The "Click Me" button, when clicked,  shows a message with the coresponding row number as shown in the picture below.




The "Remove Me" buttons delete the corresponding row. And if we remove couple of rows the page becomes like this ..




The above scenario would involve dynamic creation of table rows (tr) and cells (td) in Javascript. Let me put the solution below and then we would dissect each part of the code. Check the Full HTML and Javascript code below.

<html>
<head>
<script type='text/javascript'>
   
//// When ClickkMe button is clicked   
function checkMe(id)
{
   alert("I am Row : " + id);
}
   
// Remove any Row from the Table
function removeMe(id)
{

  // Get the Table
  var t = document.getElementById('table');
 
  // Delete the Selected Row
  t.deleteRow(id);
 
  // Re-Index the Rows Heading
  for(var j=0;j<t.rows.length; j++)
  {
     /// Index Row Numbers
     var tr = t.rows[j];
    

     // FOR IE
     if(tr.children[0].innerText)
        tr.children[0].innerText = "Row : " + j;
     // FOR Others 
     else if(tr.children[0].textContent)
        tr.children[0].textContent = "Row : " + j; 
  }
 
  /// GET all CLICK ME buttons
  var p = document.getElementsByName('button_click');
 
  /// We need to re-define the onclick behaviour of these buttons
  /// checkMe() takes corresponding row number to show the message
  for(var j=0; j<p.length; j++)
  {
    p[j].setAttribute("onclick", "checkMe("+j+")");
  }
 
  /// GET all REMOVE ME buttons
  var p = document.getElementsByName('button_remove');
 
  /// We need to re-define the onclick behaviour of these buttons
  /// removeMe() takes corresponding row number to delete
  for(var j=0; j<p.length; j++)
  {
    p[j].setAttribute("onclick", "removeMe("+j+")");
  }

}

// Addition of a new row at the end of the Table
function add_new()
{
  // GET The Table
  var t = document.getElementById('table');
 
  // GET row count
  var lastrow = t.rows.length;
 
  // Insert Row at the End
  var row = t.insertRow(lastrow);

  // leftmost Cell showing Row No :
  var cellLeft = row.insertCell(0);
  var textNode = document.createTextNode("Row : " + lastrow);
  cellLeft.appendChild(textNode);

  // Next Cell/TD for Input Element
  cellLeft = row.insertCell(1);
  var i = document.createElement('input');
  i.setAttribute('type','text');
  i.setAttribute('value',lastrow);
  i.setAttribute('name','text'+lastrow);
  cellLeft.appendChild(i);

  // Next Cell/TD for 'Click ME' button
  cellLeft = row.insertCell(2);
  i = document.createElement('input');
  i.setAttribute('type','button');
  i.setAttribute('name','button_click');
  i.setAttribute('value','Click Me');
  i.setAttribute('onclick','checkMe('+lastrow+')');
  cellLeft.appendChild(i);

  // Next cell/TD for 'Remove Me' button
  cellLeft = row.insertCell(3);
  i = document.createElement('input');
  i.setAttribute('type','button');
  i.setAttribute('name','button_remove');
  i.setAttribute('value','Remove Me');
 
  /// We define the onclick behaviour of each remove button
  i.setAttribute('onclick','removeMe('+lastrow+')');
  cellLeft.appendChild(i);

}
</script>
</head>
<body>
<table id="table"></table>
<input type='button' value='Add New' id='button' onclick='add_new()'>
</body>
</html>


Explanation ::

a. The add_new() function does a lot of job when we click the "Add New" button.
    

    1. First we reach to the table through getElementById('table') method, then we use insertRow() method to insert a new row at the position specified by lastrow. The lastrow variable holds last row's position as t.rows.length returns the total number of rows in the table. The last row created is returned in variable row.
   

   2. Now, add a new cell to the row where the text "Row : 0" would appear. The first row starts from index zero in our example. Then we create cells in that row starting form index 0. The method insertCell(0) created first cell, insertCell(1) creates second cell (td element) etc. in that row.
   

   3. For the fist cell, we create only a text node with document.createTextNode() method. After we create a node, we must append it to the cell associated with it. The statment cellLeft.appendChild(textNode); does it.
   

   4. The next cell at position 1, which was created with row.insertCell(1) is going to have an Input field which would also show Row Number. For creating any element within the HTML, we need to use document.createElement() method with element type as argument. Hence document.createElement('input') creates an input element but does not append it to the cell associated with it. Until and unless we do so ( append the input element to a <td> cell  by calling appendChild() ), it does not get rendered by the browser. Next, we add some attributes to the input element by setAttibute() method.
   

    The statement setAttribute('name','text'+lastrow); would add "name" property to that input element and assign "text0" or "text1" etc. value to that property. We would not see any effect of adding & setting the 'name' property of that text input element here, but this might be useful if we want to submit the form including the table above with some required input.
   

   5. Then we again call the appendChild() method to append the new input element to the parent cell or <td> element.
   

   6. Similarly, we create two more input element (type button) and append them to their associated cells.
   

       The following statement :
      i.setAttribute('onclick','checkMe('+lastrow+')');
      gives the input element a property like "onclick = 'checkMe(1)'".
     
       The statement :
      i.setAttribute('onclick','removeMe('+lastrow+')');
      gives the last input element a property like "onclick = 'removeMe(1)'".

      The removeMe() function actually removes the row which is passed to it as a parameter.

b. The removeMe() function is called when "Remove Me" button corresponding to any row is clicked. This function deletes the row. 

   
  For example :
   removeMe(2);
   would delete the row number 2 (the third row from top). Row number 0 would refer to the first row from the top.
  
   We use
   t.deleteRow(id); // id is the row index,
   to delete any particular row. 


It works like an array. If a table has 4 rows [ index 0,1,2,3 ] and we delete any row from this array it becomes [ index 0,1,2 ]. Again if we delete a row, it becomes [ index 0,1 ]. Deleting rows would involve some critical situation. Suppose, there are 4 rows with index 0,1,2,3 with remove button's onclick events are shown below :
   

   1st row's [index 0] "Remove Me" button's onclick event -- removeMe(0)
   2nd row's [index 1] "Remove Me" button's onclick event -- removeMe(1)
   3rd row's [index 2] "Remove Me" button's onclick event -- removeMe(2)
   4th row's [index 3] "Remove Me" button's onclick event -- removeMe(3)

   Now when we delete 2nd row [index 1] by calling removeMe(1), the row indexes become 0,1,2 as it works more like an array. But the all the "Remove Me" button's onclick events remain as shown below ...
   

   1st row's [index 0] "Remove Me" button's onclick event -- removeMe(0)
   3rd row's [index 1] "Remove Me" button's onclick event -- removeMe(2)
   4th row's [index 2] "Remove Me" button's onclick event -- removeMe(3)

   The row indexes are updated within the table while the function calls are not updated. At this situation, if we try to call the last row's removeMe(3) function, this would generate an error as index 3 is not available. Table row indexes are 0,1,2 now. The following code gets all the remove buttons in variable p, and then we change the onclick property.

   var p = document.getElementsByName('button_remove');
 for(var j=0; j<p.length; j++)
 {
     p[j].setAttribute("onclick", "removeMe("+j+")");
 }


   Similar treatment we do with all "Click Me" buttons and text heading at cell zero in each row of the table. For putting a text content inside a span or td tag, we use "innerText" for IE and "textContent" functions for other browsers.


This way, we dynamically add/delete rows to HTML table through JavaScript.

Tuesday, April 23, 2013

PHP Notes - II

1. Variable Functions :: Object methods can be called using variable names. Check out the below example.

<?php

class a
{
  public function disp($str)
  {
    echo "class a disp() says $str";
  }
}
$a  = new a;         /// Create Object
$new_func = "disp";  /// Assign function name to variable
$a->$new_func("DISPLAY");
?>


Output ::
class a disp() says DISPLAY

Explanation ::
$a->$new_func("DISPLAY") acutally calls $a->disp("DISPLAY"). Static functions can be called using variable functions as shown below.

<?php

class a
{
  static function disp()
  {
    echo "Static FN called";
  }
}
$new_func = "disp";  ///
Assign function name to variable
a::$new_func();      /// Now call the function using variable
?>


Output ::
Static FN called

Explanation ::
The function call a::$new_func() is converted to a::disp().

2. Some very interesting PHP functions ::
  
   a. If you want to know the list of extensions your PHP is using, write the following statement :
      <?php  print_r(get_loaded_extensions()); ?>
      This would list all the extensions like "Core", "zlib", "json", "xml", "mysql", "zip", "session", "curl", "soap", "ereg" etc.
  
   b. If you want to know the functions available with each extension, run the following statement :
      <?php print_r(get_extension_funcs("Core")); ?>
      This would list all functions "Core" extension offers, like "strlen", "strcmp", "each", "error_reporting", "func_num_args", "define", "function_exists", "create_function" etc.

      <?php  print_r(get_extension_funcs("mysql")); ?>
      This would list all functions "mysql" extension offers, like "mysql_connect", "mysql_close", "mysql_select_db", "mysql_query", "mysql_error", "mysql_affected_rows", "mysql_insert_id", "mysql_num_rows" etc.
  
   c. If you want to know the list of files included to the current script, run the statement below :
     
<?php print_r(get_included_files()); ?>
      This would show list of all files included to your script with the name of current script. If you do not have any script included, then the name of the current script is shown in the 0th position of the returned array. If other files are included, their names appear from 1st position onwards in the returned array.

   d. Always wanted to know about the makers of PHP? Run the statement below ..
     
<?php phpcredits (); ?>

   e. To get the OS info PHP is running on, type the statement below :
   
<?php     
    echo php_uname();
    echo "----------";
    echo PHP_OS;

    ?>


    Output ::
    Windows NT TEST-PC 6.1 build 7600 (Windows 7 Business Edition) i586
    ----------
    WINNT

3. Check out one example on PHP closures below ::

<?php
$p = 100;

/// Define the closure
$Hello['all'] = function() use ($p)
{
  echo "\$p = $p";
  $p++;
};

/// Call the function
$Hello['all']();

/// Print p
echo "\$p = $p";

?>


Output :
$p = 100
$p = 100

Some points need to be noticed in the example above.
a. If we don't use the "use ($p)" to the function definition, the anonymous function does not get access to variable $p in the parent scope.
b. The closure function tries to make changes to $p by calling $p++, but it does not changes $p in the parent scope which is evident when the second "echo" prints value of $p. If we want the closure function to get the true access to the $p in parent scope, we need to use reference in the function definition as shown below :

/// Define the closure
$Hello['all'] = function() use (&$p) //// Reference is used
{
  echo "\$p = $p";
  $p++;
};


Now, $p is incremented by 1 within the closure and hence, the second "echo" prints "$p = 101".

Friday, April 19, 2013

PHP Notes - I

Here I am discussing those small tidbits of PHP which we may not use in our PHP projects but they are very much part of core PHP. It is good to learn and remember them. I am discussing them point-wise below.

1. In PHP, variables containing Integer, Float, String or Boolean data are called Scalar variables. But variables with Null, Object, Resource or Array data won't be treated as scalar variable. We can test whether a variable is of scalar type by use of is_scalar() function.
 

<?php
$p = 100;
echo is_scalar($p);    // 1
echo is_scalar("");    // 1
echo is_scalar(false); // 1
?>

 

2. Conversion from other built-in types to objects creates stdClass objects. Check out the code below.
 

<?php
$v = (object)"standard";
var_dump( $v);
?>


Here one string ["standard"] has been converted to an Object. Check out the output below ::

object(stdClass)#1 (1) { ["scalar"]=> string(8) "standard" }

An object of built-in class stdClass is created on the fly, and its member called "scalar" holds the string "standard". Check out the another code snippet below.

<?php
$fp = fopen("test.txt", "r+");
$v = (object) $fp;
var_dump($v);
echo "<br>";
 

$v = (object) NULL;
var_dump($v);
echo "<br>";
 

$v = (object) array(1,2,3,4);
print_r($v);
?>


Output ::

object(stdClass)#1 (1) { ["scalar"]=> resource(3) of type (stream) }
object(stdClass)#2 (0) { }
stdClass Object
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
)


The first var_dump() shows that the typename of variable $fp (Resource) is stored in scalar member of stdClass object. The second var_dump() call shows an empty object when NULL was converted to object. However, this empty object does not result to be TRUE on echo empty($v); call. The print_r ($v) in the last line shows the object in array format. However we can not access each member in that object as $v->0 or $v->1 etc. Let's convert an associative array to object.

<?php
$v = (object) array("t1"=>1,"t2"=>2,"t3"=>3,"t4"=>4);
echo $v->t1 . $v->t2 . $v->t3 . $v->t4;
?>

Here, everything simply goes fine. Four members can be accessed as $v->t1, $v->t2, $v->t3, $v->t4.


3. Check out some predefined ("magic") constants used in PHP in program written below.

<?php
    class di_splay
    {
       public $name = 'Class One';
      
       function disp_lay()
       {
        echo "This PHP file is in Directory :: " . __DIR__ . "<br>";
        echo "This PHP file's full path :: " . __FILE__ . "<br>";
        echo "The name of this Function :: " . __FUNCTION__ . "<br>";
        echo "The name of this Class :: " . __CLASS__ . "<br>";
        echo "The name of this Method :: " . __METHOD__ . "<br>";
        echo "Curently Executing Line No. :: " . __LINE__ . "<br>";
       }
    }

   $di_splay = new di_splay;
   $di_splay->disp_lay();

?>


Output ::

This PHP file is in Directory :: C:\xampp\htdocs
This PHP file's full path :: C:\xampp\htdocs\test.php
The name of this Function :: disp_lay
The name of this Class :: di_splay
The name of this Method :: di_splay::disp_lay
Curently Executing Line No. :: 13

Hence the usage of constants like __DIR__, __FILE__, __FUNCTION__ is quite clear in the example above. I want to show another important point here ergarding __FILE__ constant. Check out the example below.

content of test.php ::
<?php
  ///// test.php
  include("include/test2.php");
   
  echo "This file names :: " . __FILE__ . "<br>";
  echo "This dir  names :: " . __DIR__ . "<br>";
?>


content of test2.php ::
<?php
  ///// test2.php

 
  echo "INCLUDED file names :: " . __FILE__ . "<br>";
  echo "INCLUDED dir  names :: " . __DIR__ . "<br>";
?>


Output :: 


INCLUDED file names :: C:\xampp\htdocs\include\test2.php
INCLUDED dir names :: C:\xampp\htdocs\include
This file names :: C:\xampp\htdocs\test.php
This dir names :: C:\xampp\htdocs

This clearly shows that __FILE__ and __DIR__ show filename and path of file in which they are contained. Though test2.php was included in test.php, __FILE__ in test2.php shows test2.php's properties.

Wednesday, April 17, 2013

Static Variables in PHP

1. Static variables should be declared as shown in the example below. Parse error would be raised if we assign an expressions to them.

<?php
function foo()
{
   static $i = 0;             // Valid
   static $j = $i + 10;       // Invalid as a expression is assigned
   static $j = loo($i + 10);  // Invalid as explained above
}

function loo($i)
{
  return $i * $i;
}
?>


2. Check the code below to see some more on static variables.

<?php
function foo()
{
   static $j = loo; 
   $j++;
   echo "<br>$j";
}
foo();
foo();
foo();
?>


Output :
Notice: Use of undefined constant loo - assumed 'loo' in C:\xampp\htdocs\test.php on line 4

lop
loq
lor

Note : the 'loo' is assumed to be a constant which was not defined earlier. Had it been defined before, the Notice would have gone away. Check the code below.

<?php
define("loo","A"); 
function foo()
{
   static $j = loo;  /// Constant can be assigned
   $j++;
   echo "<br>$j";
}
foo();
foo();
foo();
?>


Output :

B
C
D

Note : PHP characters behaved like integers in the code above; Actually the internal ASCII value is incremented/decremented like in C.

3. Inside a class, static variable can't be assigned with any constructor/function as shown in example below.

<?php
/// External Function
function foo()
{
  return 1;
}

//// Class Declaration
class One
{
    /// Initialize the static variable $var
    static $var = foo(); 

    /// Static function to retun static variable
    static function disp()
    {
       print ++ self::$var;
    }
}

One::disp();
One::disp();
One::disp();
?>


Output : An error message is shown.

Explanation : The statement static $var = foo(); is wrong, static variable can not be initialized with a function/constructor call. However the code can be written the following way to work properly.

<?php
/// External Function
function foo()
{
  return 1;
}

/// Static Variable Initialization, with 1 [returned by foo()]
One::$var = foo();

//// Class Declaration
class One
{
    /// Initialization of static variable is already done
    static $var; 

    /// Static function to return static variable
    static function disp()
    {
       print ++ self::$var;
    }
}

One::disp();  // Prints 2
One::disp();  // Prints 3
One::disp();  // Prints 4
?>


The code above is quite self-explanatory. We did an external initialization of static variable $var outside of the actual class definition. However this was possible because the static variable is was not declared as private. Check out the code below.

<?php
/// External Function
function foo()
{
  return 100;
}

class One
{
    ///// Private Static Member
    private static $var ;
   
    ///// Initialize Static Member against external functions
    static function init()
    {
      self::$var = foo();
    }
   
    /// Static function to retun static variable
    static function disp()
    {
        print ++ self::$var;
    }
}

One::init();  /// Initialize with 100
One::disp();  /// Prints 101
One::disp();  /// Prints 102
One::disp();  /// Prints 103
?>


Inheritance of static method is shown in the following example.

<?php
class one
{
    static protected $test = "class one";
    public static function static_test()
    {
       echo self::$test ;
    }
}

class two extends one
{
    //// This has to be static, otherwise re-declaration error occurs
    static protected $test = "class two";
}

two::static_test(); /// class one
?>


In this example, self:: is resolved using the class in which the method belongs. "this" can't be used inside a static method. The static_test() function does not exist in class two, but in class one. Hence "class one" is printed ... this is a limitation of self:: ... kind of "Early Binding" effect in C++. To get the effect of "Late Binding", we need to change the line

echo self::$test ;

to

echo static::$test ; /// This calls for Late Static Binding

As a result, "class two" is printed. But the construct "static::" can only be used with static properties. Another example where a different approach for accessing static properties is shown..


<?php
class Foo
{
   // Define static property

   public static $my_static = 1;
}
 

// Inheritance
class Bar extends Foo
{

}

// Parent Object

$foo = new Foo();
print $foo::$my_static; // 1
 

// Increment
$foo::$my_static ++;

// Child Object

$boo = new Bar();
print $boo::$my_static; // 2
?>


The program above access static properties using object. All the following constructs access the same static property..

echo Foo::$my_static;  // Class Name used
echo Bar::$my_static;  // Class Name used
echo $boo::$my_static; // Object used

Invoking static property of any abstract class is also possible.
<?php
abstract class Foo
{
    public static $bar = "100";
}
echo  ++Foo::$bar ; // prints 101

?>

HTML Form Submission

Check out some notes on HTML forms which I think is very useful.

1. If we use a form like this ::

<form name='f' action = "test.php?id=123&color=blue" method='GET'>
<input type='text' name='fname'>
<input type='submit' name='btn_submit' value='submit'>
</form>


the form is submitted to URL :: test.php?fname=john&btn_submit=submit (though the action is set to test.php?id=123&color=blue)The pre-defined URL parameters "id" and "color" are overwritten. Hence the "id" and "color" are never captured at the Server end. 


But if we change the method to "POST", all the four parameters ("id", "color", "fname" and "btn_submit") are captured. PHP $_GET global variable receives "id", "color", $_POST gets "fname" and "btn_submit" parameters while $_REQUEST receives all fours of them.

2. If we use Image Submit buttons and suppose that element has a name 'submit_btn', we would receive two element's values at the server end. This is shown below.
 

<?php
if(!empty($_GET))
    print_r( $_GET );
?>


<form name='f' method='GET'>
Enter your name <input type='text' name='c_name'>
<input type='image' name='btnsubmit' src='images/submit_btn.jpg'>
</form>


The above form consists of an input text element and another input element with type image. The second element works as a Submit button. When we submit the form, the URL becomes quite similar to this ...

http://127.0.0.1/test.php?c_name=&btnsubmit.x=2&btnsubmit.y=1

The btnsubmit.x and btnsubmit.y captures the co-ordinates on the Submit buttons's image where the click occurred. If you make the input element like this (remove the name attribute from the element itself) ::

<input type='image' src='images/submit_btn.jpg'>

the URL would become ::

http://127.0.0.1/test.php?c_name=cder&x=0&y=0

See that btnsubmit.x has been changed to only x and btnsubmit.y has been changed to only y.

3. Check and following code :

<html>
<body>
<!-- SCRIPT STARTS -->
<script type='text/javascript'>
function f_name(fname)
{
  document.f.fname.value = fname;
  document.f.submit();
 
}
</script>
<!-- SCRIPT ENDS -->

<!-- FORM STARTS -->
<form name='f' >
<input type='text' name='fname' placeholder="Enter your first name">
<input type='submit' name='submit' value='submit'>
</form>
<!-- FORM ENDS -->

I am <a href='javascript:;' onclick="f_name('Michael')">Michael</a> | <a href='javascript:;' onclick="f_name('John')">John</a> | <a href='javascript:;' onclick="f_name('Ramon')">Ramon</a>

</body>
</html>


The form looks like the pic below.





The form can be submitted two ways,
a. Enter your first name in the textbox given and hit the Submit button
b. Click on any one of the 3 links given at the bottom. This calls up the Javascript function f_name() which then submits the form though the statement ::
   document.f.submit();

But wait, it gave an error message?

...















"document.f.submit is not a function". 

This is a very common error I have seen while working with various web-forms.

The reason :: We can access all the elements inside a form as shown below.

document.form_name.element_name

example :


//// Changes value of 'fname' element within the form names 'f'
document.f.fname.value = "John";  

Similarly, we can access the Submit button in the form above ::

//// This would change the Button text
document.f.submit.value = 'Hit Me !!!'

"submit" is the name of that Submit button input element. Hence, when we try to submit the form by calling document.f.submit() in the f_name() function, the Javascript engine identifies that it is name of an element existing within the form, hence it shows an error message which causes the form not to be submitted at all.

Solution :: Simply renaming the submit button to anything other than 'submit' would do. Even 'Submit' [S is in caps] makes it working as Javascript, being case-sensitive, distinguishes "Submit" to be different from "submit". Hence document.f.submit(); submits the form without any hassle as the submit button element has now been accessible with :: document.f.Submit  (S is in caps).

Tuesday, April 16, 2013

Print Pascal's Triangle in PHP

Pascal's triangle is named after French mathematician Blaise Pascal. More info on this triangle can be found here. In this triangle, from 3rd row onwards, each number in the triangle is the sum of the two numbers appearing immediately above it. A small triangle is shown below.

                    1
                  1   1
                1   2   1
              1   3   3   1
            1   4   6   4   1
         1   5   10   10   5   1
       1   6   15   20   15   6   1
     1   7   21   35   35   21   7   1



How we try to solve this problem?

a. For the first row, we don't put a logic.
b. For 2nd row, we create an array of two ones. Then we print it.
c. For 3rd row onwards, we calculate sum of 2 digits appearing in the previous row.
   For 3rd row :: we create an array, set the first and last elements in the array to 1. Then we sum taking each 2 elements in the previous row i.e the array available in 2nd row. We start doing this sum from element index 1.
   For 4th row :: we create an array, set the first and last elements in the array to 1. Then we sum taking each 2 elements in the previous row i.e the array available in 3rd row.
   .... and so on till the total number of lines we are asked to print.
  
Check the code below which is quite self-explanatory.

<?php
//// Define Total Lines of the Pyramid
$total_lines = 10;

//// Define a Base Array
$base_arr = array(1,1);

//// PRINT LINE 1
pri_nt(1);

//// PRINT LINE 2
pri_nt(2, $base_arr);

//// Main LOOP to print from Line 3 onwards
for($i=3;$i<=$total_lines-2;$i++)
{
  //// CREATE ARRAY
  $arr = range(1,$i);
 
  //// Set 1st & Last item set to 1
  $arr[0] = $arr[count($arr)-1] = 1; 
 
  //// Get Previous Row's Array values for summation
  //// We start with index 1, zeroth element always holds 1
  for( $k=1; $k<count($arr)-1; $k++)
  {
    $arr[$k] = $base_arr[$k] + $base_arr[$k-1];
  }
 
  //// PRINT the new ARRAY
  pri_nt( $i, $arr );
 
  //// Preserve Current Array
  $base_arr = $arr;
}

function pri_nt( $cur_line, $arr = "" )
{
  global $total_lines;
 
  //// Printing Logic for 2nd Line Onwards
  if( is_array( $arr ) && !empty($arr) )
  {
     //// PRINT SPACES
     for( $i=1; $i<($total_lines-$cur_line)*2; $i++)
       echo "&nbsp;";
   
     //// PRINT DIGITS
     for( $i=0; $i<count($arr); $i++)
       echo "
&nbsp;&nbsp;&nbsp;" . $arr[$i] . "";
    
     //// New Line
     echo "<br>";
  }
  else   //// PRINT the ONE star at LINE 1
  {
    
     //// PRINT Spaces
     for( $i=1;$i<($total_lines-$cur_line)*2; $i++)
       echo "
&nbsp;";
   
     //// PRINT DIGIT 1
     echo "
&nbsp;&nbsp;&nbsp;"."1";
   
     //// New Line
     echo "<br>";   
  }

}
?>

Print ASCII in PHP

Printing ASCII characters in PHP is easy. However various browsers would render the characters differently on the screen. Check the code below.

<?php
for($i=0;$i<=255;$i++)
{
  $b = chr($i);
  echo "<br>($i) :: [$b]";
}
?>


The above code would generate the output as shown in the picture at right::


...

Here is the output I noticed on various browsers.

Opera 12.15  :: Showed all characters
IE 8 :: Showed characters ranging 0-127, 128 onwards showed character '�' instead.
Safari 5.1.7 :: Did not show characters ranging 0-31 only [9,10,13 excluded]
Firefox 19 :: Did not show characters ranging 0-31 [9,10,13 excluded], and 128 onwards showed a question mark instead. UTF-8 encoding was enabled though.
Chrome 26.0.1410.64 m :: Did not show characters ranging 0-31 [9,10,13 excluded]

I changed the Line 4 as shown below ...

echo "<br>($i) :: [$b] [&#$i;]";

Check the output below :: [As shown in Firefox, Firefox now can show characters 128 onwards]

(123) :: [{] [{]
(124) :: [|] [|]
(125) :: [}] [}]
(126) :: [~] [~]
(127) :: [] []
(128) :: [€] [�]
(129) :: [] [�]
(130) :: [‚] [�]
(131) :: [ƒ] [�]
(132) :: [„] [�]
(133) :: […] [�]
(134) :: [†] [�]
(135) :: [‡] [�]
(136) :: [ˆ] [�]

Note : If the number is higher than 255, it would give the number % 256. Which means the statement :

echo chr(256);

would render zero ... 256 % 256 = 0

HTML characters related stuffs available at Bob Baumel's Page

How to read a file backward in PHP?

Reading backward means, suppose a text file has 25 lines; and we want to read that file starting from line 25th fist, then line no. 24, then 23rd, 22nd and so on till line number 1.

Check the logic below to achieve this goal. Each line in a text file has a particular position within the file.

a. Start reading the file from the beginning (position zero) and store the current file pointer position into an array. This way, we would store the position of all the lines (starting position) in that array.
b. When reading is complete, we iterate the array backward.
c. For each iteration of that array, we put the file pointer pointing to the array value i.e starting position of a line.

d. Then we read that line and print on screen.

Now check the PHP implementation below.
 

<?php
//// OPEN FILE
$filename = "car_names.txt";
$fp = fopen($filename,"r+")
or
die("Could not open file :: " . error_get_last()['message'] );

//// Create an array to store various positions in the file
$line_beg = array(0);  ///// First line is at position 0

//// Run the loop for reading the file from beginning
while( ($buffer = fgets($fp,80))!== false )
{
  //// Store the starting position of each line to the array
  $line_beg[] = ftell( $fp );   


//// Start iterating the Array backward
for($i = count($line_beg)-1; $i >=0; $i--)
{
  //// Move the file pointer to desired location
  fseek($fp, $line_beg[$i] );
  

  //// Read that line
  $buffer = fgets($fp, 80 );
  if( trim($buffer) != "" )
  {
      //// Print the line
      echo "Line : $i, Content : $buffer<br>";
  }

}

//// Close file
fclose ($fp);
?>


Note :
1. error_get_last() holds various Error related info in array format, hence error_get_last()['message'] points to 'message' key of that array which contains the whole Error message. The whole array looks like as shown below in case the file car_names.txt was not opened successfully ::
 

Array
(
    [type] => 2
    [message] => fopen(car_names.txt): failed to open stream: No such file or directory
    [file] => C:\xampp\htdocs\test.php
    [line] => 2
)


2. $line_beg = array(0);
We initialized the array with the beginning of the first line (position zero)

The code above was really too big when we can do it in only four lines as shown below.

<?php
//// Read Content, create array of all lines in the file
$file = file("$filename");   
//// Reverse the Array
$file = array_reverse($file);
//// Iterate and Print
foreach($file as $f)
{
    echo $f."<br />";
}
?>

Friday, April 12, 2013

PHP unset()

Unset destroys specified variables. I am going to show some good examples to explain how unset is applied to variables and the outcome.

Example 1 :
<?php
$foo = 'bar';
echo "At first : [$foo]";    // bar
modify_foo();
echo "<br>After modify_foo : [$foo]";  // Modified foo

destroy_foo();     // foo destroyed 

echo "<br> After destroy_foo foo is :: $foo";  
// Modified foo ... outside variable retains its value

destroy_foo_reference($foo);     // foo reference destroyed

echo "<br> At Last foo is :: $foo";  
// Modified foo ... outside variable retains its value

function destroy_foo()
{
    global $foo;
    echo "<br>Before [$foo]";  // Modified foo
    unset($foo);
    echo @"<br>After [$foo]";  

   // Outputs nothing as $foo is unavailable to this function
}

function destroy_foo_reference(&$foo)
{

    echo "<br>Before [$foo]";  // Modified foo
    unset($foo);
    echo @"<br>After [$foo]";  

   // Outputs nothing as $foo is unavailable to this function
}

function modify_foo()
{
    global $foo;
    $foo = "Modified foo";
}
?>


Output :
At first : [bar]
After modify_foo : [Modified foo]
Before [Modified foo]
After []
After destroy_foo foo is :: Modified foo
Before [Modified foo]
After []
At Last foo is :: Modified foo

The following points need to be noted.
a. Unlike some programming languages like Python, PHP functions can be declared anywhere within the code. C, C++ also have the similar structure. Functions may be declared after actual calls to them.
b. The keyword "global" brings the global version of a variable available for use and modification within any function. The function modify_foo() changes the value of $foo to "Modified foo".
c. In the destroy_foo() function, we get the modified value "Modified foo", but then the variable $foo is unset. As a result, the $foo variable in calling context is not destoyed, rather a local version destroyed so that $foo is no more available within destroy_foo() function after the unset call.
d. Next, we called a destroy_foo_reference() function which accepts $foo as a reference. In this function also, unset actually removes a local copy of $foo variable from the scope of called function only. After the function call, the $foo variable in the calling environment with old value is still available to the following part of the script. After unset call in both the above functions, we have used a "@" character with statement just to suppress the errors :

echo @"<br>After [$foo]";  // $foo is no more available. Hence this cause errors.

Example 2:
Unset() with Static variables bahave the same way as shown in previous examples. Static variables get their original value even they are unset within the function. Checkout the example below, it is self-explanatory.

<?php
function f()
{
 static $foo = 1;
 echo "<br>Beginning of f() function : [$foo]";
 $foo++;
 unset($foo);
 echo @"<br>End of f() function : [$foo]";
}

f();
f();
f();
?>


Output :
Beginning of f() function : [1]
End of f() function : []
Beginning of f() function : [2]
End of f() function : []
Beginning of f() function : [3]
End of f() function : []

$foo gets incremented in each function call and its original value is restored even after unset is called upon.

Note : Unset can not be used with variable functions. It is not a function rather a function construct.
 

<?php
$foo = "unset";
$foo();   //// Would give undefined function unset() error.
?>


Example 3:
Check out another example where unset has been used with objects and classes

<?php
class test
{
  var $foo = 1;             /// Instance Variable
 
  public function show()    /// Display
  {
    echo @"<br> \$foo is now : $this->foo";
  }
 
  public function incr()   /// Increment
  {
    $this->foo++;
    unset($this->foo);  /// Unset
  }
}

$a = new test();
$a->show();     /// 1     
var_dump($a);  
$a->incr();     /// Unset 
$a->show();     /// $foo is already gone
var_dump($a);
?>


Output:
$foo is now : 1
object(test)#1 (1) { ["foo"]=> int(1) }
$foo is now :
object(test)#1 (0) { }

The output is quite expected. The two var_dump calls show it all. The object variable $foo was removed in the incr() function call which is captured in the 2nd var_dump call.