Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Old 08-29-2005, 08:40 AM   #1 (permalink)
DJMaze
Senior Contributor
 
DJMaze's Avatar
 
Join Date: Mar 2005
Posts: 676
DJMaze is on a distinguished road
PHP5 Tips and tricks

PHP5 is already there for some time but hosting providers and others don't upgrade for several reasons. One of the main reasons is incompatible scripts so in this topic i will write some things once in a while which might be usefull to make your scripts compatible, and some tips and tricks which will ONLY work in PHP5.

To start of, PHP5 has more restrictions on class handling and a lot of new features inside classes.

### CLASS ISSUES ###

var isn't allowed
PHP Code:
class var_test
{
    var 
$bob# fails

Instead just strip var or if you write your script PHP5 only use one of the following
PHP Code:
class var_test
{
    public 
$bob# item can be accessed everywhere
    
protected $bob# limits access to inherited classes and itself
    
private $bob# limits visibility only to the class that defines the item

Another thing that isn't allowed is instance reassigning like
PHP Code:
class assign_test
{

    public function 
assign()
    {
        
$this = new Class(); # dies immediately
    
}

### CLASS TIPS ###

Normally you can access inside a class $this if it's a instance
PHP Code:
class this_test
{
    public function echo()
    {
        
$this->foo();
    }
    public function 
echo_dyn()
    {
        
this_test::foo();
    }
    public function 
foo()
    {
        echo 
'foo';
    }
}
$test = new this_test();
$test->echo(); # outputs foo
this_test::echo() # fails
this_test::echo_dyn() # outputs foo 
The above script is messy when you are extending classes
PHP Code:
class this_test
{
    public function echo()
    {
        
$this->foo();
    }
    public function 
foo()
    {
        echo 
'foo';
    }
}
class 
this_test2 extends this_test
{
    public function echo()
    {
        
this_test::foo();
    }
}
$test = new this_test2();
$test->echo(); # outputs foo
this_test2::echo() # outputs foo 
This way it overwrites echo() but is pretty nasty in very advanced scripts.
So PHP5 gives additional features like self:: and parent:: which i will explain.

self::
With this you call a function inside the class itself and not thru extension or anything. This means if you overwrite a function it will not succeed with the self operator.
PHP Code:
class this_test
{
    public function echo()
    {
        
self::foo();
    }
    public function 
foo()
    {
        echo 
'foo';
    }
}
class 
this_test2 extends this_test
{
    public function 
foo()
    {
        echo 
'bar';
    }
}
this_test2::echo(); # outputs foo instead of bar
this_test2::foo(); # outputs bar 
parent::
With this you call a function in the parent of the class. This means that if you overwrite a function you have still access to the original function. This is extremely usefull if you want to add functionality to a function.
PHP Code:
class this_test
{
    public function 
foo()
    {
        echo 
'foo';
    }
}
class 
this_test2 extends this_test
{
    public function 
foo()
    {
        
parent::foo()
        echo 
'bar';
    }
}
this_test::foo(); # outputs foo
this_test2::foo(); # outputs foo and bar 
If you like all this info i will keep adding stuff here once in a while
DJMaze is offline   Reply With Quote
Old 08-29-2005, 09:21 AM   #2 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,489
sde is on a distinguished road
PHP5 is backwards compatible in at least the first of the 2 examples you point out. Although it is depricated, the keyword var will not break PHP5.

i do host websites and there are a couple other reasons i hesitate to make the switch. i recently ported a pretty large scale enterprise web app (for my day job) from PHP4 to PHP5 and here are a couple of details that really broke the product.

1. array_merge will break. array_merge supported mixed input in PHP4. for example, you could merge an array with a non array and it would put them both into the same array. but now if you put a non array into an argument of array_merge, it will break.

2. unset() . unset() seems to break if there is a variable that hasn't been set or is st to null. i don't remember the specifics, but i know there were problems related to unsetting vars that weren't set.

3. when comparing a string to an integer, the string evaluates to zero before it is compared. this means: 'abcdefg' == 0. You can probably imagine the problems it may cause if you might be expecting a 0 as valid input to something that is checking on a string and the zero has not been cast to a string ahead of time.

great thread. the topic would make a great article.
__________________
Mike
sde is offline   Reply With Quote
Old 08-29-2005, 10:21 AM   #3 (permalink)
DJMaze
Senior Contributor
 
DJMaze's Avatar
 
Join Date: Mar 2005
Posts: 676
DJMaze is on a distinguished road
Yeah your points are also a few of those pescy issues.
There are more of those but i just wanted to start with classes since everyone seems to be OOP minded these days.

Anyway since you like it maybe we all should go on with things we see and notice that would make it a good tutorial regarding all issues and changed vs PHP 4.
DJMaze is offline   Reply With Quote
Old 08-29-2005, 04:03 PM   #4 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
Thanks for the tips DJMaze. I've been holding out on running php5 for awhile now, mostly due to low penetration in hosting providers. I guess I'll have to give it a look though.
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 08-30-2005, 02:28 AM   #5 (permalink)
DJMaze
Senior Contributor
 
DJMaze's Avatar
 
Join Date: Mar 2005
Posts: 676
DJMaze is on a distinguished road
Quote:
Originally Posted by sde
3. when comparing a string to an integer, the string evaluates to zero before it is compared. this means: 'abcdefg' == 0. You can probably imagine the problems it may cause if you might be expecting a 0 as valid input to something that is checking on a string and the zero has not been cast to a string ahead of time.
To avoid this you could try to use is_numeric(), is_int() or empty().
The issue with empty() is that it returns TRUE on: NULL, FALSE, '', 0 and array().
is_int() checks if the value is a integer instead of a string ('abcdefg' === 0 <= triple =)
is_numeric('3e00') will return true as this function supports e-notation.

So maybe just a regex would be best ereg('^[0-9]+$', 'abcdefg')
DJMaze is offline   Reply With Quote
Old 08-30-2005, 06:51 AM   #6 (permalink)
sde
Moderator
 
sde's Avatar
 
Join Date: May 2002
Location: us.ca
Posts: 4,489
sde is on a distinguished road
i ended up just casting the input to the function to a string and then i could compare it just fine.

PHP Code:
<?
function foo($a){
  
$a = (string)$a;

  if(
$a=="0"){
    
// do this
  
}
  ...
}
?>
i don't have the exact problem in memory atm, but i know the tripple = was not working for me either.
__________________
Mike
sde is offline   Reply With Quote
Old 08-31-2005, 03:07 AM   #7 (permalink)
DJMaze
Senior Contributor
 
DJMaze's Avatar
 
Join Date: Mar 2005
Posts: 676
DJMaze is on a distinguished road
doh that i didn't think of that.
DJMaze is offline   Reply With Quote
Old 10-13-2005, 08:29 PM   #8 (permalink)
DJMaze
Senior Contributor
 
DJMaze's Avatar
 
Join Date: Mar 2005
Posts: 676
DJMaze is on a distinguished road
AS said i will add some more tips & tricks

### CLASS TIPS ###

E_STRICT is an added error_reporting option in PHP5, but what does it do ?
Copy a class tip example of the first post and put it into a PHP file and add an additional line.
PHP Code:
<?php

error_reporting
(E_ALL E_STRICT); # <= added line

class this_test
{
    public function echo()
    {
        
$this->foo();
    }
    public function 
echo_dyn()
    {
        
this_test::foo();
    }
    public function 
foo()
    {
        echo 
'foo';
    }
}
$test = new this_test();
$test->echo();
this_test::echo();
this_test::echo_dyn();
You will notice that the page is showing 'Runtime Notices' like:
Non-static method this_test::echo() should not be called statically

If you want to call functions inside a class staticly (class::function) besides dynamicly ($this->function) you only have to add the keyword 'static' to the function identifier.

PHP Code:
error_reporting(E_ALL E_STRICT);

class 
this_test
{
    public static function echo()
    {
        
$this->foo();
    }
    public static function 
echo_dyn()
    {
        
this_test::foo();
    }
    public static function 
foo()
    {
        echo 
'foo';
    }
}
$test = new this_test();
$test->echo();
this_test::echo();
this_test::echo_dyn(); 
### STRING CONTENT ###

There are several ways to compare the contents of a string like ereg, eregi, preg_match and strpos.
ereg is similar to preg_match which uses regular expressions and eregi is the case-insensitive way. Although ereg is slower then preg_match it is easier if you don't understand regular expressions very well.
But the underdog is strpos and in PHP5 the stripos (case-insensitive) which are actualy the fastest compare functions for normal strings.
PHP Code:
$haystack 'I love CodeNewbie.com';
$needle 'love';
strpos($haystack$needle); # case-sensitive
stripos($haystack$needle); # PHP 5 case-insensitive 
NOTE: Do keep in mind that strpos could return 0 since 0 is the first character.
So if you want to check if needle exists inside a string then use the triple =
PHP Code:
if (stripos($haystack$needle) !== false) {
  echo 
"$needle found";

DJMaze is offline   Reply With Quote
Old 10-13-2005, 08:32 PM   #9 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
Nice DJMaze have you considered working this thread into an article or two for the php section?
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 10-14-2005, 07:00 AM   #10 (permalink)
DJMaze
Senior Contributor
 
DJMaze's Avatar
 
Join Date: Mar 2005
Posts: 676
DJMaze is on a distinguished road
something like that tekno, while i'm building PHP5 software sometimes there are issues between PHP 4 and 5 when people convert my code.
I just write down some PHP 5 added features so newbies understand the differences.
DJMaze is offline   Reply With Quote
Old 01-05-2006, 06:19 AM   #11 (permalink)
DJMaze
Senior Contributor
 
DJMaze's Avatar
 
Join Date: Mar 2005
Posts: 676
DJMaze is on a distinguished road
Class members can be overloaded to run custom code defined in your class by defining specially named methods (__set, __get, __call).
This is not adviced to use since it doesn't handle class inside class and it slows down your scripts.

However it can be used as nice factory system. The trick here is that you can make a factory of methods that you don't need often or need to be loaded before some script execution but not used unless certain actions are triggerd.

For an example you have a script that offers a HTML output template system but, one of your pages outputs RSS then it's useless to load the template class.
Instead you could use a factory with overloaders and that way the template is only loaded when it's realy needed to increase speed.

PHP Code:
<?php
class My_Handler
{
    protected 
$class_file;
    protected 
$class_name;
    protected 
$class_inst;

    public function 
__construct($class_name)
    {
        
$this->class_name $class_name;
        
$this->class_inst null;
    }

    public function 
__call($method$args)
    {
        if (!
$this->class_inst$this->load_inst();
        
$count count($args);
        if (
$count == 0) {
            return 
$this->class_inst->$method();
        } else if (
$count == 1) {
            return 
$this->class_inst->$method($args[0]);
        } else if (
$count == 2) {
            return 
$this->class_inst->$method($args[0], $args[1]);
        } else {
            
$call[0] =& $this->class_inst;
            
$call[1] = $method;
            return 
call_user_func_array($call$args); # this is slow
        
}
    }

    public function 
__get($nm)
    {
        if (!
$this->class_inst$this->load_inst();
        
$this->class_inst->$nm;
    }
    public function 
__set($nm$val)
    {
        if (!
$this->class_inst$this->load_inst();
        
$this->class_inst->$nm $val;
    }

    public function 
name() { return $this->class_name; }

    
# Check if class is already loaded else load it into memory
    
private function load_inst()
    {
        if (
$this->class_inst) return;
        
$file strtolower($this->class_name).'.php';
        if (!
class_exists($this->class_namefalse) && !file_exists($file)) {
            throw new 
Exception("Class {$this->class_name} does not exist");
        }
        require_once(
$file);
        
$this->class_inst = new $this->class_name($this);
    }

}

$template My_Handler($template);

if (
$_GET['rss']) {
    echo 
'rss'# template class NOT loaded
} else {
    
$template->include('index.html'); # template class gets loaded
    
$template->display();
}
DJMaze is offline   Reply With Quote
Old 05-20-2006, 05:32 PM   #12 (permalink)
DJMaze
Senior Contributor
 
DJMaze's Avatar
 
Join Date: Mar 2005
Posts: 676
DJMaze is on a distinguished road
class __destruct() and register_shutdown_function()

Since PHP 5.0.5 the order of destruction and calling shutdown functions has been changed.
If you think you can call object instances thru these then they will fail (without notice)
The issues:
1. object instances get destroyed BEFORE the shutdown functions are called.
2. object instances are destroyed in order of creation NOT in reverse order.

To avoid these issues you must create your own "destruction collector" and register all object instances that need access to other objects.
We can achieve this by writing a class that has an __destruct() and create an instance of the class right at the beginning of execution.

PHP Code:
<?php
class my_proper_destructor
{
    protected 
$destroyers = array();

    public function 
add($class_instance)
    {
        if (
is_class($class_instance))
            
$this->destroyers[] = $class_instance;
    }

    public function 
__destruct()
    {
        foreach(
$this->destroyers as $des)
            
$des->on_destroy();
    }
}
$destruct = new my_proper_destructor();

// Your code goes here
Now when you write a class that needs other objects on destruction you slightly modify this class to use
PHP Code:
class session
{
    function 
__construct()
    {
        global 
$destruct;
        
$destruct->add($this);
    }
    function 
on_destroy()
    {
        
// destruction code goes here instead of using __destruct()
    
}

DJMaze is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Java tips and tricks Belisarius Java 18 08-06-2003 12:18 AM


All times are GMT -8. The time now is 11:50 AM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8