Showing posts with label php5. Show all posts
Showing posts with label php5. Show all posts

Sunday, June 7, 2009

XMLWriter

the PHP5 XMLWriter class allows to easily create XML well-formed documents.

The most useful methods:
  • openURI($output) // use 'php://output' as argument to stream directly
  • startDocument('1.0') // add the initial tag. 1st argument : xml version
  • writeElement('hr') // write the empty node [hr/]
  • writeAttribute('src','img.gif') //write the attribute (inside the last node) and value
    e.g: [img src="http://www.blogger.com/img.gif" /]
  • writeElement('b','content') // write node with content "[b]content[/b]"
  • startElement('body') //add the start node [body]
  • endElement() //close the last element started. e.g: [/body]
  • How to create nodes with attributes and text:
    startElement('textarea')
    writeAttribute('name','area1')
    text('default text')
    endElement()

    output:
    [textarea name="area"]default text[/textarea]
  • endDocument()
  • flush()
  • there are other methods to write comments, DTD, CData etc... view the official documentation.
Note: I used square brackets instead of "minor or greater than" because of blogspot editor limitation.

Complete Example: RSS Feed !!

@date_default_timezone_set("GMT");
$xml = new XMLWriter();
// Output directly to the user
$xml->openURI('php://output');
$xml->startDocument('1.0');
$xml->setIndent(2);
//rss
$xml->startElement('rss');
$xml->writeAttribute('version', '2.0');
$xml->writeAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');

//channel
$xml->startElement("channel");

//title, desc, link, date
$xml->writeElement('title', 'PHP news');
$xml->writeElement('description', 'description....');
$xml->writeElement('link', 'http://www.example.com/rss.hml');
$xml->writeElement('pubDate', date("D, d M Y H:i:s e"));

//item !
$xml->startElement("item");
$xml->writeElement('title', 'news 1');
$xml->writeElement('link', 'http://www.example.com/1.html');
$xml->writeElement('description', 'descr 1');
$xml->writeElement('pubDate', date("D, d M Y H:i:s e"));
//cat
$xml->startElement('category');
$xml->writeAttribute('domain', 'http://www.example.com/cat1.htm');
$xml->text('News');
$xml->endElement();
//end item
$xml->endElement();
//end channel
$xml->endElement();
// end rss
$xml->endElement();
//end doc
$xml->endDocument();
//flush
$xml->flush();


output:




Saturday, June 6, 2009

ArrayAccess: use object as an array, file manager example

ArrayAccess (PHP5) allows to treat objects as an array.
View below the interface scheme, with explanatory comments

ArrayAccess { //PHP5 built-in Interface
// returns true/false if the element in the position $offset exists/doesn't exist
abstract public boolean offsetExists ( string $offset )
// returns the element at the position $offset
abstract public mixed offsetGet ( string $offset )
// set the element at the position $offset to the value $value
abstract public void offsetSet ( string $offset , string $value )
//delete the element at the position $offset
abstract public void offsetUnset ( string $offset )
}

minimal implementation (to copy to quickly use).

class ... implements ArrayAccess
{
public function
offsetExists( $offset ){}
public function
offsetGet( $offset ){}
public function
offsetSet( $offset , $value ){}
public function
offsetUnset( $offset ){}
}


An useful example !
Let's write a class which allows to easily manage files content, like an array.

$obj["file.txt"] = "content"; //write "content" into file.txt
$obj["file.txt"] .= "content"; //append "content" into file.txt
print $obj["file.txt"] ; //print the content of file.txt
unset($obj["file.txt"]); //delete file.txt
if (isset($obj["file.txt"])) {} ; // equivalent to file_exists("file.txt")


/* class to easy manage files content like an array */
class filesManager implements ArrayAccess
{
private $basePath;
private
$prefix;
private
$suffix;

public function
__construct($basePath="", $prefix="", $suffix=""){
$this->basePath = $basePath;
$this->prefix = $prefix;
$this->suffix = $suffix;
}

//get files basepath + prefix
private function path($file){
return
$this->basePath.$this->prefix.$file.$this->suffix;
}

//file exists ?
public function offsetExists( $file ){
return
file_exists($this->path($file));
}

//read file
public function offsetGet( $file ){
if (!
$this->offsetExists($file)) return "";
$handle = fopen($this->path($file), "r");
$contents = fread($handle, filesize($this->path($file)));
fclose($handle);
return
$contents;
}

//write new content into a file
public function offsetSet( $file , $value ){
$handle = fopen($this->path($file), "w");
fwrite($handle, $value);
fclose($handle);
}

//delete file
public function offsetUnset( $file ){
unlink($this->path($file));
}

}




//example of use

/* the files will be read and created in
* the folder "data", with prefix "_" and
* suffix ".txt" */
$f = new filesManager("data/","_",".txt");

//create the file "data/_notes.txt" and write "file start" inside !
if (!isset($f['notes']))
$f['notes'] = "file start !";

//append
$f['notes'] .= "\nanother line";

//print all the content
print $f['notes'];

//delete
unset($f['notes']);

Exceptions in PHP5

  • PHP5 supports Exception model, like C++/C# and Java.

syntax to catch exception:

try {
//code which can launch an exception
// [...]
// manual exception throw
throw new Exception("thrown exception");
//not executed ! (throw command is caught below
print "not printed!";
}
catch(
Exception $e) { print $e->getMessage();}

this code prints : "thrown exception".
It's possibile to throw an exception inside a catch construct. The new exception will be caught in the external try-catch block.

try {
try{
throw new
Exception("internal exception");
}
catch (
Exception $e) { throw new Exception($e->getMessage()); }
print
"not printed!";
}
catch(
Exception $e) { print $e->getMessage(); }

This code prints: "internal exception"

Structure of "Exception" built-in class and inheritance

class Exception
{
protected
$message = 'Unknown exception'; // exception message
protected $code = 0; // user defined exception code
protected $file; // source filename of exception
protected $line; // source line of exception

function __construct($message = null, $code = 0);

final function
getMessage(); // message of exception
final function getCode(); // code of exception
final function getFile(); // source filename
final function getLine(); // source line
final function getTrace(); // an array of the backtrace()
final function getTraceAsString(); // formatted string of trace

/* Overrideable */
function __toString(); // formatted string for display
}

In case of extension, remember to call the superclass constructor in the extended class constructor
parent::__construct()

Multiple catch constructs
It's allowed to specify more than one catch after a try construct.
If the exception doesnt' match with the argument, it will be caught to the next catch block.
Note: an Exception object match also with the objects of its subclasses. Mind the order !

class MyException extends Exception {/* ...*/ }

try{
throw new
MyException("");
}
catch (
MyException $e) {// <-- match ! executed !
print "MyException";
}
catch (
Exception $e) { // never executed
print "Exception";
}

And ...

try{
throw new
MyException("");
}
catch (
Exception2 $e) { print "Exception"; }
catch (
Exception $e) { // <-- match ! executed !
print "Exception";
}
catch (
MyException $e) { print "MyException"; }

PHP5 Namespaces

Namespaces are available in PHP as of PHP 5.3.0
A namespace is a container with classes, function and constants (also available in PHP>5.3.0), similar to the namespaces in C++/C# and packages in Java. As indicated in the official PHP documentation, namespaces help us to solve name collisions and use alias to call long name classes/functions.

definition syntax:
// no code or html allowed here ! ( except declare() )
namespace MyProject; // standard namespace

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }

//it's possibile to define another namespace in the same file
// however it's not a good idea
namespace MyProject2\Sub\Level; //namespace with hierarchy

//brackets are allowed
namespace MyProject3 {
//content.
}
?>

use of namespace:

print \CONSTANT;
print \class;
print \method();

where is the relative or absolute namespace path where constants, classes and methods will be searched first (e.g. MyProject2\Sub\Level).
Absolutes relative namespace paths must start with "\".
If no namespaces are specified, the constant, class or method will be searched in the current namespace (or file if the namespace is not declared).

use of aliases:
use My\Full\Classname as Another;
// instead of use "My\Full\Classname" as namespace, you can use "Another"


Late static Bindings (PHP >= 5.3.0)

in programming languages, binding is the association of the values with the identifiers.
  • association before running: early binding
  • association at runtime: late binding (also called virtual or dynamic)
PHP5 supports the classic late binding. At runtime, PHP5 distinguishes the superclass from the subclasses object, respecting the overridden methods rules.
The late binding for static methods are available only from PHP 5.3.0

Late static binding (PHP >= 5.3.0)

Let's consider binding for static methods:

Consider this class, in which the static method f() calls (using "self::") the static internal method print() which prints "A" :

class A {
static function print() { print
"A"; }
static function
f() { print self::print(); }
}

Now consider the extension "B" which overrides the method print() which prints "B"

class B extends A {
static function print() { print
"B"; }
// f() inherited !
}

B::f(); // A !! no binding ! "self::" point to superclass, not to subclass !

------------------------------------------

PHP 5.3.0 supports the pointer "static::" to support Late Static binding

class A {
static function print() { print
"A"; }
static function
f() { print static::print(); }
}
class
B extends A {
static function print() { print
"B"; }
// f() inherited !
}

B::f(); //B. late static bindings!!

In according to Late Static Bindings, if we call the static method f() of the class B, the inherited method f() will consider static as a pointer to the current class, that is B, and the the invoked method will call print() of the subclass B (and will print "B").
In other words, "static" is a pointer to the "current class"

 

PHP and tips|PHP