全部博文(42)
分类:
2008-10-18 22:23:15
原创,转载请声明出处 http://blog.chinaunix.net/u/27731/showart.php?id=1328279
作者:流水孟春 121169238(at)qq.com
1、动态语言
动态语言就是能够在运行时改变程序结构和变量类型的语言。例如:新的类和对象可以被加载和创建,新的函数或方法可以加入和去除等等。
动态语言都被设计成弱类型,也就是说变量被赋值以后才能确定它的数据类型,当代码在实际执行时,才会检测变量是否被非法使用。
2、PHP动态特性:
特性1、弱类型变量
PHP变量是弱类型变量就意味着,我们不需要声明变量的类型,在运行时自动检测变量的类型,并且可以认为改动变量的类型。
<?php
// PHP弱类型变量例子
$test = 1;
print gettype($test) . ": $test\n";
$test = 1.23456789;
print gettype($test) . ": $test\n";
$test = 'test'; // 变量自动改变类型
print gettype($test) . ": $test\n";
$test = array('t'=>'HI,I m from an array!');
settype($test, 'object'); // 改变变量的类型
print gettype($test) . ": {$test->t}\n";
// 测试变量类型
if(is_object($test)) {
print "Test Type: My Type Is object.\n";
} else {
print gettype($test);
}
?>
弱类型并不意味着代码不安全,或者不健壮。极限编程已经给成为一种软件开发方法。这个方法侧重测试,使用全面的单元测试方案来驱动开发过程。通过不同环境
下执行所编写的代码,就可以保证代码的安全性和健壮性。经验证明,在弱类型语言中,综合运用弱类型和单元测试通常比传统系统编程语言的类型检查更好(请参
考《Thinking in Java》作者Bruce Eckel的博客http://mindview.net/WebLog/log-0025)。
特性2、可变变量
一个变量的变量名可以动态的设置和使用
<?php
// 可变变量例子
$var = 'hi';
$$var = 'hello';
print $var;
print $$var;
print $hi; // 等价于上一行
?>
特性3、变量函数
这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且将尝试执行它。除了别的事情以外,这个可以被用于实现回调函数,函数表等等。
<?php
// 变量函数例子
// 无参数函数
function a(){
print "i'm a\n";
}
// 有参数函数
function b($param) {
print "i'm b, param: $param\n";
}
$x = 'a';
$x();
$x = 'b';
$x('xxxxxxxxxxx');
?>
特性4、可变长度参数列表
调用函数的时候,函数的参数个数可以不一样
<?php
function foo() {
$numargs = func_num_args();
print "Number of arguments: $numargs\n";
print "the third argument: " . func_get_arg(2) . "\n";
}
foo(1, 2, '...@...');
foo(1, 2, '############', 4);
?>
特性5,从数组中导出变量
把数组中的数据复制出变量,将键名当作变量名,值作为变量的值。
<?php
// 例1
$a = array('x' => 100, 'y'=> 200, 'z' => 300);
// 从数组中将变量导入到当前的符号表
extract($a); // 和extract相反的函数是compact()
print "$x $y $z";
?>
<?php
// 例2
$a = array(100, 200, 300);
list($x, , $z) = $a;
print "$x $z";
?>
特性6,用一个数组的值作为其键名,另一个数组的值作为其值,创建一个数组
<?php
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);
print_r($c);
?>
特性7,动态创建函数
<?php
// lambda函数
$newfunc = create_function('$a,$b', 'return "$a + $b = " . $a + $b;'); // 创建了一个匿名函数
print "\nNew anonymous function: $newfunc\n";
print $newfunc(2, 4);
print "\n";
// 效果类似于
function test($a,$b){
return "$a + $b = " . $a + $b;
}
print test(2, 4);
?>
特性8、自动加载对象
可以定义一个 __autoload 函数,它会在试图使用尚未被定义的类时自动调用。
<?php
// ClassA.php, 这段代码写在ClassA.php
class A {
function __construct() {
print 'yeah!';
}
}
?>
<?php
function __autoload($className) {
require_once $className . '.php';
}
// 这段代码写在b.php
new A(); // 程序运行到这里的时候,A类未定义,将自动调用__autoload()函数
?>
特性9、__get和__set代替所有对属性变量数组的访问
<?php
class Setter{
public $n;
private $x = array("a" => 1, "b" => 2, "c" => 3);
private function __get($nm) {
echo "Getting [$nm]\n";
if (isset($this->x[$nm])) {
$r = $this->x[$nm];
print "Returning: $r\n";
return $r;
} else {
echo "Nothing!\n";
}
}
private function __set($nm, $val) {
echo "Setting [$nm] to $val\n";
if (isset($this->x[$nm])) {
$this->x[$nm] = $val;
echo "OK!\n";
} else {
echo "Not OK!\n";
}
}
private function __isset($nm) {
echo "Checking if $nm is set\n";
return isset($this->x[$nm]);
}
private function __unset($nm) {
echo "Unsetting $nm\n";
unset($this->x[$nm]);
}
}
$foo = new Setter();
$foo->n = 1;
$foo->a = 100;
$foo->a++;
$foo->z++;
var_dump(isset($foo->a)); //true
unset($foo->a);
var_dump(isset($foo->a)); //false
// this doesn't pass through the __isset() method
// because 'n' is a public property
var_dump(isset($foo->n));
var_dump($foo);
?>
特性10、自定义未定义的方法
你调用未定义方法时,方法名和方法接收的参数将会传给__call方法
<?php
class Caller {
private $x = array(1, 2, 3);
private function __call($m, $a) {
print "Method $m called:\n";
print_r($a);
return $this->x;
}
}
$foo = new Caller();
$a = $foo->test(1, "2", 3.4, true);
print_r($a);
?>
特性11、自定义错误、异常处理
设置使用自定义错误或异常处理函数后,当发生错误或异常时将调用自定义的处理函数代替系统错误处理函数。
<?php
set_error_handler('error_handler'); // 设置错误时调用的自定义处理错误函数,设置自定义异常处理函数为set_exception_handler()
print $a/0; // 这里逻辑错了,调用error_handler()报错
function error_handler($errno, $message, $filename, $line) {
if ($errno & (E_ALL ^ E_NOTICE)) {
$types = array(
1 => 'error',
2 => 'warning',
4 => 'parse error',
8 => 'notice',
16 => 'core error',
32 => 'core warning',
64 => 'compile error',
128 => 'compile warning',
256 => 'user error',
512 => 'user warning',
1024 => 'user notice',
2048 => 'strict warning'
);
print "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
print $types[$errno] .': '. $message .' in '. $filename .' on line '. $line .'.';
print "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
exit;
}
}
?>
特性12、高可配置性
可修改范围为
PHP_INI_USER 的 配置选项可在用户的PHP脚本或Windows注册表中设置
PHP_INI_PERDIR 的 配置选项可在 php.ini, .htaccess 或 httpd.conf 中设置
PHP_INI_SYSTEM 的 配置选项可在 php.ini or httpd.conf 中设置
PHP_INI_ALL 的 配置选项可在各处设置
我们要熟悉在php.ini中修改php的配置,还会经常在php脚本中修改脚本中可修改的配置项。
可以使用 ini_set()函数或专门修改运行时配置的函数来改变可修改范围为PHP_INI_ALL
<?php
// 修改php的配置参数
ini_set('session.save_path', 'D:/temp'); // 修改配置让脚本把session文件保存到D:/temp目录
?>
特性13、代码中执行php脚本特性14、php的工作模型
(这个特性详细的在http://blog.csdn.net/phphot/archive/2008/02/19/2105600.aspx)
作为一种纯解释型语言,PHP脚本在每次被解释时进行初始化,在解释完毕后终止运行。这种运行是互相独立的,每一次请求都会创建一个单独的进程或线程,来解释相应的页面文件。页面创建的变量和其他对象,都只在当前的页面内部可见,无法跨越页面访问旧电脑回收。