Tuesday, September 23, 2008

Write your PHP script file

The PHP scripts will have the logic of rewriting the URL (you can use any other language, Perl for example).What the code will exactly look like is depend upon your requirement. But again, for the sack of completeness I will show you a working example. Note that the same script should work on both Windows and Linux without any modification.

#!/usr/bin/php
mysql_connect("localhost","username","password");
mysql_select_db("Database");

$filename = "log.txt";
if (!$handle = fopen("$filename", "a+")) {
echo "Cannot open file ($filename)";
exit;
}
while( $url = trim(fgets(STDIN)))
{
$sql = "select * from users order by rand() limit 1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
$name = $row['username'];
$today = date("j-n-Y, G:i:s");
if (fwrite($handle, $today."|".$url."|\r\n") === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
if(fwrite(STDOUT, $name.".html\r\n") === FALSE)
{
fwrite($handle, "CANT WRITE $url\n");
}
}
fclose($handle);
exit;
?>

Write your rewrite rules in your .htaccess file

What your rewrite rules will be in your .htaccess file will largely depend upon your requirements. But for the sack of completeness I am going to include the sample script.


RewriteEngine On
Options +FollowSymLinks
RewriteBase /
RewriteRule ^([a-z]+[0-9]*_?[a-z]*[0-9]*)$ ${links:$1} [NC]

The $1 argument will be passed to our PHP script ‘rewriting_script.php’ (mentioned by the label ‘links’) and the return value will be substituted.

RewriteMap PRG By Example Using PHP For Apache Mod_Rewrite

For the purpose of Search Engine Optimization many web developers uses apache mod_rewrite module for URL rewriting so that they can produce search engine friendly URLs. Although for most of the purpose RewriteRule directive is enough to get the job done but for the greater flexibility one can use RewriteMap directive. Unfortunately I didn’t see any example on the web for RewriteMap in details. So I investigated the matter in detail myself and after spending hours and trial and error I finally succeeded in using RewriteMap. I will show you how to do it in both Windows and Linux. Even though the differences are minor but they are enough to grind your brain into syrup (at least this is what happened with me). To use RewriteMap these three steps are needed to be done.

* Change httpd.conf file in Apache conf directory.
* Write RewriteRule in .htaccess (or in the other apache configuration files).
* Write your PHP script file.

RewriteMap example

Although chances are lower that you will be running Linux in your local machine but the fact is when we enter in the arena of WWW the scenario changes dramatically. Yes, welcome to the world of Linux. Internet is powered mostly by Linux so we will take our first example on Linux OS.

Change Configuration file.

open your httpd.conf file and add these lines in your configuration file.
Codes for Apache Httpd.conf for Linux



RewriteEngine on
RewriteMap links "prg:/usr/bin/php /var/www/vhosts/example.com/httpdocs/rewriting_script.php"

Codes for Apache Httpd.conf for Windows



RewriteEngine on
RewriteMap links "prg:C:/Progra~1/PHP/php.exe d:/localhost/rewrite_test/rewrite_url.php"


‘links’ is the label given so that we can refer to it later. In doubles quotes is the path to php interpreter and then full path to your rewriting script. Note that how “Program Files” folder is converted into DOS compatible file path. It is necessary otherwise it wont work. Put these line of codes after all modules have been loaded using LoadModule directive in httpd.conf file. Put it in the wrong place for example under directive and then test configuration of apache web server and you will get an error saying “RewriteMap not allowed here”.

Friday, September 05, 2008

Strings

A string is series of characters. In PHP, a character is the same as a byte, that is, there are exactly 256 different characters possible. This also implies that PHP has no native support of Unicode. See utf8_encode() and utf8_decode() for some Unicode support.

Note: It is no problem for a string to become very large. There is no practical bound to the size of strings imposed by PHP, so there is no reason at all to worry about long strings.

Syntax
A string literal can be specified in three different ways.

single quoted
double quoted
heredoc syntax

Single quoted
The easiest way to specify a simple string is to enclose it in single quotes (the character ').

To specify a literal single quote, you will need to escape it with a backslash (\), like in many other languages. If a backslash needs to occur before a single quote or at the end of the string, you need to double it. Note that if you try to escape any other character, the backslash will also be printed! So usually there is no need to escape the backslash itself.

Note: In PHP 3, a warning will be issued at the E_NOTICE level when this happens.

Note: Unlike the two other syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.

echo 'this is a simple string';

echo 'You can also have embedded newlines in
strings this way as it is
okay to do';

// Outputs: Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"';

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\\*.*?';

// Outputs: You deleted C:\*.*?
echo 'You deleted C:\*.*?';

// Outputs: This will not expand: \n a newline
echo 'This will not expand: \n a newline';

// Outputs: Variables do not $expand $either
echo 'Variables do not $expand $either';
?>

Double quoted
If the string is enclosed in double-quotes ("), PHP understands more escape sequences for special characters:

Table 11.1. Escaped characters

sequence meaning
\n linefeed (LF or 0x0A (10) in ASCII)
\r carriage return (CR or 0x0D (13) in ASCII)
\t horizontal tab (HT or 0x09 (9) in ASCII)
\v vertical tab (VT or 0x0B (11) in ASCII) (since PHP 5.2.5)
\f form feed (FF or 0x0C (12) in ASCII) (since PHP 5.2.5)
\\ backslash
\$ dollar sign
\" double-quote
\[0-7]{1,3} the sequence of characters matching the regular expression is a character in octal notation
\x[0-9A-Fa-f]{1,2} the sequence of characters matching the regular expression is a character in hexadecimal notation



Again, if you try to escape any other character, the backslash will be printed too! Before PHP 5.1.1, backslash in \{$var} hasn't been printed.

But the most important feature of double-quoted strings is the fact that variable names will be expanded. See string parsing for details.

Heredoc
Another way to delimit strings is by using heredoc syntax ("<<<"). One should provide an identifier (followed by new line) after <<<, then the string, and then the same identifier to close the quotation.

The closing identifier must begin in the first column of the line. Also, the identifier used must follow the same naming rules as any other label in PHP: it must contain only alphanumeric characters and underscores, and must start with a non-digit character or underscore.

Warning
It is very important to note that the line with the closing identifier contains no other characters, except possibly a semicolon (;). That means especially that the identifier may not be indented, and there may not be any spaces or tabs after or before the semicolon. It's also important to realize that the first character before the closing identifier must be a newline as defined by your operating system. This is \r on Macintosh for example. Closing delimiter (possibly followed by a semicolon) must be followed by a newline too.

If this rule is broken and the closing identifier is not "clean" then it's not considered to be a closing identifier and PHP will continue looking for one. If in this case a proper closing identifier is not found then a parse error will result with the line number being at the end of the script.

It is not allowed to use heredoc syntax in initializing class members. Use other string syntaxes instead.

Example 11.3. Invalid example

class foo {
public $bar = <<bar
EOT;
}
?>



Heredoc text behaves just like a double-quoted string, without the double-quotes. This means that you do not need to escape quotes in your here docs, but you can still use the escape codes listed above. Variables are expanded, but the same care must be taken when expressing complex variables inside a heredoc as with strings.

Example 11.4. Heredoc string quoting example

$str = <<Example of string
spanning multiple lines
using heredoc syntax.
EOD;

/* More complex example, with variables. */
class foo
{
var $foo;
var $bar;

function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}

$foo = new foo();
$name = 'MyName';

echo <<My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>



Note: Heredoc support was added in PHP 4.

Variable parsing
When a string is specified in double quotes or with heredoc, variables are parsed within it.

There are two types of syntax: a simple one and a complex one. The simple syntax is the most common and convenient. It provides a way to parse a variable, an array value, or an object property.

The complex syntax was introduced in PHP 4, and can be recognised by the curly braces surrounding the expression.

Simple syntax
If a dollar sign ($) is encountered, the parser will greedily take as many tokens as possible to form a valid variable name. Enclose the variable name in curly braces if you want to explicitly specify the end of the name.

$beer = 'Heineken';
echo "$beer's taste is great"; // works, "'" is an invalid character for varnames
echo "He drank some $beers"; // won't work, 's' is a valid character for varnames
echo "He drank some ${beer}s"; // works
echo "He drank some {$beer}s"; // works
?>
Similarly, you can also have an array index or an object property parsed. With array indices, the closing square bracket (]) marks the end of the index. For object properties the same rules apply as to simple variables, though with object properties there doesn't exist a trick like the one with variables.

// These examples are specific to using arrays inside of strings.
// When outside of a string, always quote your array string keys
// and do not use {braces} when outside of strings either.

// Let's show all errors
error_reporting(E_ALL);

$fruits = array('strawberry' => 'red', 'banana' => 'yellow');

// Works but note that this works differently outside string-quotes
echo "A banana is $fruits[banana].";

// Works
echo "A banana is {$fruits['banana']}.";

// Works but PHP looks for a constant named banana first
// as described below.
echo "A banana is {$fruits[banana]}.";

// Won't work, use braces. This results in a parse error.
echo "A banana is $fruits['banana'].";

// Works
echo "A banana is " . $fruits['banana'] . ".";

// Works
echo "This square is $square->width meters broad.";

// Won't work. For a solution, see the complex syntax.
echo "This square is $square->width00 centimeters broad.";
?>
For anything more complex, you should use the complex syntax.

Complex (curly) syntax
This isn't called complex because the syntax is complex, but because you can include complex expressions this way.

In fact, you can include any value that is in the namespace in strings with this syntax. You simply write the expression the same way as you would outside the string, and then include it in { and }. Since you can't escape '{', this syntax will only be recognised when the $ is immediately following the {. (Use "{\$" to get a literal "{$"). Some examples to make it clear:

// Let's show all errors
error_reporting(E_ALL);

$great = 'fantastic';

// Won't work, outputs: This is { fantastic}
echo "This is { $great}";

// Works, outputs: This is fantastic
echo "This is {$great}";
echo "This is ${great}";

// Works
echo "This square is {$square->width}00 centimeters broad.";

// Works
echo "This works: {$arr[4][3]}";

// This is wrong for the same reason as $foo[bar] is wrong
// outside a string. In other words, it will still work but
// because PHP first looks for a constant named foo, it will
// throw an error of level E_NOTICE (undefined constant).
echo "This is wrong: {$arr[foo][3]}";

// Works. When using multi-dimensional arrays, always use
// braces around arrays when inside of strings
echo "This works: {$arr['foo'][3]}";

// Works.
echo "This works: " . $arr['foo'][3];

echo "You can even write {$obj->values[3]->name}";

echo "This is the value of the var named $name: {${$name}}";
?>
Note: Functions and method calls work since PHP 5.

Note: Parsing variables within strings uses more memory than string concatenation. When writing a PHP script in which memory usage is a concern, consider using the concatenation operator (.) rather than variable parsing.

String access and modification by character
Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string using square array-brackets like $str[42] so think of a string as an array of characters.

Note: They may also be accessed using braces like $str{42} for the same purpose. However, using square array-brackets is preferred because the {braces} style is deprecated as of PHP 6.


Example 11.5. Some string examples

// Get the first character of a string
$str = 'This is a test.';
$first = $str[0];

// Get the third character of a string
$third = $str[2];

// Get the last character of a string.
$str = 'This is still a test.';
$last = $str[strlen($str)-1];

// Modify the last character of a string
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';

// Alternative method using {} is deprecated as of PHP 6
$third = $str{2};

?>



Note: Accessing by [] or {} to variables of other type silently returns NULL.

Useful functions and operators
Strings may be concatenated using the '.' (dot) operator. Note that the '+' (addition) operator will not work for this. Please see String operators for more information.

There are a lot of useful functions for string modification.

See the string functions section for general functions, the regular expression functions for advanced find&replacing (in two tastes: Perl and POSIX extended).

There are also functions for URL-strings, and functions to encrypt/decrypt strings (mcrypt and mhash).

Finally, if you still didn't find what you're looking for, see also the character type functions.

Converting to string
You can convert a value to a string using the (string) cast, or the strval() function. String conversion is automatically done in the scope of an expression for you where a string is needed. This happens when you use the echo() or print() functions, or when you compare a variable value to a string. Reading the manual sections on Types and Type Juggling will make the following clearer. See also settype().

A boolean TRUE value is converted to the string "1", the FALSE value is represented as "" (empty string). This way you can convert back and forth between boolean and string values.

An integer or a floating point number (float) is converted to a string representing the number with its digits (including the exponent part for floating point numbers). Floating point numbers can be converted using the exponential notation (4.1E+6).

Note: The decimal point character is defined in the script's locale (category LC_NUMERIC). See setlocale().

Arrays are always converted to the string "Array", so you cannot dump out the contents of an array with echo() or print() to see what is inside them. To view one element, you'd do something like echo $arr['foo']. See below for tips on dumping/viewing the entire contents.

Objects in PHP 4 are always converted to the string "Object". If you would like to print out the member variable values of an object for debugging reasons, read the paragraphs below. If you would like to find out the class name of which an object is an instance of, use get_class(). As of PHP 5, __toString() method is used if applicable.

Resources are always converted to strings with the structure "Resource id #1" where 1 is the unique number of the resource assigned by PHP during runtime. If you would like to get the type of the resource, use get_resource_type().

NULL is always converted to an empty string.

As you can see above, printing out the arrays, objects or resources does not provide you any useful information about the values themselves. Look at the functions print_r() and var_dump() for better ways to print out values for debugging.

You can also convert PHP values to strings to store them permanently. This method is called serialization, and can be done with the function serialize(). You can also serialize PHP values to XML structures, if you have WDDX support in your PHP setup.

String conversion to numbers
When a string is evaluated as a numeric value, the resulting value and type are determined as follows.

The string will evaluate as a float if it contains any of the characters '.', 'e', or 'E'. Otherwise, it will evaluate as an integer.

The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.

$foo = 1 + "10.5"; // $foo is float (11.5)
$foo = 1 + "-1.3e3"; // $foo is float (-1299)
$foo = 1 + "bob-1.3e3"; // $foo is integer (1)
$foo = 1 + "bob3"; // $foo is integer (1)
$foo = 1 + "10 Small Pigs"; // $foo is integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2)
$foo = "10.0 pigs " + 1; // $foo is float (11)
$foo = "10.0 pigs " + 1.0; // $foo is float (11)
?>
For more information on this conversion, see the Unix manual page for strtod(3).

If you would like to test any of the examples in this section, you can cut and paste the examples and insert the following line to see for yourself what's going on:

echo "\$foo==$foo; type is " . gettype ($foo) . "
\n";
?>

Do not expect to get the code of one character by converting it to integer (as you would do in C for example). Use the functions ord() and chr() to convert between charcodes and characters.

Floating point numbers

Floating point numbers (AKA "floats", "doubles" or "real numbers") can be specified using any of the following syntaxes:

$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
?>
Formally:
LNUM [0-9]+
DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*)
EXPONENT_DNUM ( ({LNUM} | {DNUM}) [eE][+-]? {LNUM})
The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (that's 64 bit IEEE format).

Floating point precision
It is quite usual that simple decimal fractions like 0.1 or 0.7 cannot be converted into their internal binary counterparts without a little loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8 as the result of the internal representation really being something like 7.9999999999....

This is related to the fact that it is impossible to exactly express some fractions in decimal notation with a finite number of digits. For instance, 1/3 in decimal form becomes 0.3333333. . ..

So never trust floating number results to the last digit and never compare floating point numbers for equality. If you really need higher precision, you should use the arbitrary precision math functions or gmp functions instead.

Converting to float
For information on when and how strings are converted to floats, see the section titled String conversion to numbers. For values of other types, the conversion is the same as if the value would have been converted to integer and then to float. See the Converting to integer section for more information. As of PHP 5, notice is thrown if you try to convert object to float.

Integers

An integer is a number of the set Z = {..., -2, -1, 0, 1, 2, ...}.

See also: Arbitrary length integer / GMP, Floating point numbers, and Arbitrary precision / BCMath

Syntax
Integers can be specified in decimal (10-based), hexadecimal (16-based) or octal (8-based) notation, optionally preceded by a sign (- or +).

If you use the octal notation, you must precede the number with a 0 (zero), to use hexadecimal notation precede the number with 0x.

Example 11.1. Integer literals

$a = 1234; // decimal number
$a = -123; // a negative number
$a = 0123; // octal number (equivalent to 83 decimal)
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
?>

Formally the possible structure for integer literals is:

decimal : [1-9][0-9]*
| 0

hexadecimal : 0[xX][0-9a-fA-F]+

octal : 0[0-7]+

integer : [+-]?decimal
| [+-]?hexadecimal
| [+-]?octal


The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). PHP does not support unsigned integers. Integer size can be determined from PHP_INT_SIZE, maximum value from PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.

Warning
If an invalid digit is passed to octal integer (i.e. 8 or 9), the rest of the number is ignored.

Example 11.2. Octal weirdness

var_dump(01090); // 010 octal = 8 decimal
?>




Integer overflow
If you specify a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, if you perform an operation that results in a number beyond the bounds of the integer type, a float will be returned instead.

$large_number = 2147483647;
var_dump($large_number);
// output: int(2147483647)

$large_number = 2147483648;
var_dump($large_number);
// output: float(2147483648)

// it's true also for hexadecimal specified integers between 2^31 and 2^32-1:
var_dump( 0xffffffff );
// output: float(4294967295)

// this doesn't go for hexadecimal specified integers above 2^32-1:
var_dump( 0x100000000 );
// output: int(2147483647)

$million = 1000000;
$large_number = 50000 * $million;
var_dump($large_number);
// output: float(50000000000)
?>
Warning
Unfortunately, there was a bug in PHP so that this does not always work correctly when there are negative numbers involved. For example: when you do -50000 * $million, the result will be -429496728. However, when both operands are positive there is no problem.

This is solved in PHP 4.1.0.


There is no integer division operator in PHP. 1/2 yields the float 0.5. You can cast the value to an integer to always round it downwards, or you can use the round() function.

var_dump(25/7); // float(3.5714285714286)
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7)); // float(4)
?>

Converting to integer
To explicitly convert a value to integer, use either the (int) or the (integer) cast. However, in most cases you do not need to use the cast, since a value will be automatically converted if an operator, function or control structure requires an integer argument. You can also convert a value to integer with the function intval().

See also type-juggling.

From booleans
FALSE will yield 0 (zero), and TRUE will yield 1 (one).

From floating point numbers
When converting from float to integer, the number will be rounded towards zero.

If the float is beyond the boundaries of integer (usually +/- 2.15e+9 = 2^31), the result is undefined, since the float hasn't got enough precision to give an exact integer result. No warning, not even a notice will be issued in this case!

Warning
Never cast an unknown fraction to integer, as this can sometimes lead to unexpected results.

echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
?>
See for more information the warning about float-precision.


From strings
See String conversion to numbers

From other types

Caution
Behaviour of converting to integer is undefined for other types. Currently, the behaviour is the same as if the value was first converted to boolean. However, do not rely on this behaviour, as it can change without notice.

Booleans

This is the easiest type. A boolean expresses a truth value. It can be either TRUE or FALSE.

Note: The boolean type was introduced in PHP 4.

Syntax
To specify a boolean literal, use either the keyword TRUE or FALSE. Both are case-insensitive.

$foo = True; // assign the value TRUE to $foo
?>

Usually you use some kind of operator which returns a boolean value, and then pass it on to a control structure.

// == is an operator which test
// equality and returns a boolean
if ($action == "show_version") {
echo "The version is 1.23";
}

// this is not necessary...
if ($show_separators == TRUE) {
echo "
\n";
}

// ...because you can simply type
if ($show_separators) {
echo "
\n";
}
?>

Converting to boolean
To explicitly convert a value to boolean, use either the (bool) or the (boolean) cast. However, in most cases you do not need to use the cast, since a value will be automatically converted if an operator, function or control structure requires a boolean argument.

See also Type Juggling.

When converting to boolean, the following values are considered FALSE:

the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Every other value is considered TRUE (including any resource).
Warning
-1 is considered TRUE, like any other non-zero (whether negative or positive) number!


var_dump((bool) ""); // bool(false)
var_dump((bool) 1); // bool(true)
var_dump((bool) -2); // bool(true)
var_dump((bool) "foo"); // bool(true)
var_dump((bool) 2.3e5); // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array()); // bool(false)
var_dump((bool) "false"); // bool(true)
?>