先解释一下题目,最近这段时间突然就忙了起来,预计之后还要更忙,一天忙来忙去却不知道在忙些啥,人也一直很累,生理心理都是。
Android这块公司已经安排了人手,暂时就先放一放,等js真正熟悉了,再回头来学,先入门一下php,作为调剂,提高点情绪。
PHP,大名是HyperText Preprocessor,与ASP,JSP并称为web 3p。但从本身名字来看,ASP和JSP的P,指的都是Pages,因此还是有些特殊的。
<?php echo 'This is from php' ?> <p>This is html</p> <?php echo 'We omitted the last closing tag';
如果php代码是在一个文件最后部分,那它的闭合标签是可以省略的,并且官方提倡在某些情况(some cases)下省略,但这某些情况具体指哪些,不省略又会带来什么问题,就只能等待日后自己发掘了。 官方永远是官方,无论是在政治圈还是IT圈,说的话都是永远一半,不可不信,不可全信。
按变量类型来分:
$pen = 'ball'; echo "this is $pen"
会输出this is ball,复杂的情况,比如多层嵌套,可求助于'{}'。 <<<XXX...XXX;
的格式,作用与双引号大致相同,要注意的是结尾的定界符必须是另起一行,并且不能包含除';’外的多余字符,并且heredoc不能用来初始化类的属性。 <<<'XXX'...XXX;
的格式,作用与单引号大致相同,并且能用来初始化任何静态数据(static data context),具体static data context指的是什么,现在也不是很明确。 unset
函数,注意,unset并不会重置最大下标,如 $arr = array(1); unset($arr[0]); $arr[] = 2; print_r($arr);
,输出的是’Array ( [1] => 2 )',其余的常用函数可见
$a + $b
表示将$b数组合并到$a数组,不覆盖相同键。
get_resource_type
函数获得具体信息。 var_dump
输出包含类型的变量具体信息,或者用
is_xxx
函数来判别是否某类型,不提倡使用
gettype
,返回值可能根据php版本的不同而不同。
if (x) ...
,在php中,假如$x变量未定义的话会抛出一个E_NOTICE级别的错误,因此一般采用
if (empty($x)) ...
或
if (is_null($x)) ...。
的写法,
is_null
只对null或undefined返回true,相反的函数是
isset
,而
empty
对空字符串,空数组,false,0,0.0和'0'都会返回true。
settype
函数显式改变类型。
按变量作用来分:
$a = 'hi'
。 $a = 'hi'; $$a = 'world';
,同于定义$hi变量,不过这并不是完全动态的,而是在运行到该行代码时,取得$a的值作为该变量的命名。 function t() { static $a = 1; return ++$a; }
,t函数共享同一个变量$a。 $a = 4; function t() { global $a; $a = 5; }
,实际上函数内的$a是相当于全局$a的一个引用,等同于$a = 4; function t() { $a = &$GLOBALS['var']; $a = 5; }
,关于引用的具体解释,看下文。
define(CONST, '...')
,支持表达式。 const CONST = '...'
,不支持表达式,并且由于编译时定义的原因,必须写在全局域中。其实除ie外,js也支持这种常量定义的方式。 $my_file = @file ('non_existent_file') or die ("Failed opening file: error was '$php_errormsg'");
。 $output = `ls -la`;
。 之所以特别提到这两个东东,是因为这两个看似函数的东东并不是函数,而归为控制结构,并且使用频率很高。
千万注意,require,并不像网上到处说的是在编译时处理的,无论判断条件真假,都会载入,经测试,require和include一样,也支持判断结构,也支持变量为参数,也可以出现在函数内部,区别就是载入出错的时候require会抛出错误,停止执行,而include只是给个警告。猜测可能是新版的php作了更改,具体哪个版本开始支持的就不得而知了。
尽信书不如无书,经验教训啊,同样的情况在学习js的时候也遇到几次,希望大家能尽量的自己测试一下,不要哪里抄一段就完事。
当allow_url_fopen
配置为真的时候,require和include甚至支持从远程载入文件
function test(&$arg) {}
。 function test($arg = 'hi') {}
。 function test(string $s) {}; test(3);
会报一个Fatal Error。 function test() {};$str = 'test';$str();
。 var $var1 = 1;
写法,等同于pulbic。 __autoload
,不需要require 'A.php'
加载类文件,在new一个对象的时候,会自动检测是否有该类定义,如没有则自动调用__autoload
函数,当然,由于需要IO操作,有时会造成性能开销较大。 public function __construct()
,构造函数,假如没有找到构造函数的话,php会寻找类的同名函数作为构造函数,函数不会自动调用父类的相应方法,需要用parent::__construct();
显式调用。 public function __destruct()
,构造函数,同样需要parent::__destruct();
显式调用父类方法,禁止抛出异常,否则会导致一个严重错误。 public function __set($name, $value)
,在设置未定义属性时自动调用。 public function __get($name)
,在读取未定义属性时自动调用。 public function __call($name, $arguments)
,调用未定义非静态方法时自动调用。 public static function __callStatic($name, $arguments)
,调用未定义静态方法时自动调用。 public function __isset($name)
,调用isset
时自动调用。 public function __unset($name)
,调用unset
时自动调用。 public function __sleep()
,调用serialize
时自动调用。 public function __wakeup()
,调用unserialize
时自动调用。 public function __toString()
,和js中的toString一样,在需要隐式转换为String时自动调用。 public static function __set_state($arr)
,在调用var_export
时自动调用,恕我愚钝,实在想不出这个函数的作用。 public function __clone()
,在调用clone时自动调用。默认情况下,php都是采用浅拷贝,在需要深拷贝的时候则需要我们自己覆写__clone
的方法。 class A { public static function who() { echo __CLASS__; } public static function test() { self::who(); } public static function test2() { static::who(); } } class B extends A { public static function who() { echo __CLASS__; } } A::test();// A B::test();// A A::test2(); // A B::test2(); // B,test方法输出始终是'A',而test2输出则是根据调用的类来判定。
首先,要区别引用与指针(pointer)的概念。指针是指向内存地址的变量,如
int *a, *b; int c = 1, d = 2; a = &c; b = &c; *a = 3; // *b = 3, c = 3 a = &d; *a = 4; // *b = 3, c = 3, 这里声明了两个指针a和b,它们都指向c变量所在的内存区域,当给*a赋值时,即改变a所指向内存区域的值,*b和c都变成了3,之后将d变量所在内存区域的地址赋给a,即a指向了d所在内存,这时给*a赋值并不会影响*b和c。
引用是指对同一变量内容取的不同名称,如
$a = 1; $b = &$a; $b = 2; // $a = 2 unset($b);// $a = 2, 这里$b是$a的引用,表示$a和$b只是值为1的变量的不同名称,就像文件的快捷方式,所以改变$b的值,$a的值也随之改变。而unset($b)表示取消了$b这个名称,$a仍是2。
在php中,除了变量引用外还有参数引用和返回值引用,先看代码。
function &t() { return 5; } function t2(&$a) { } function t3() { return 5; } t(); t2(); t2($a = 5); t2(t3());,调用t会报一个notice错误,第一次调用t2时会报Fatal Error,为什么?仔细理解引用的定义,是指向某个变量内容的不同名称,当文件都没有的时候,哪来的快捷方式。 但是,t2的第二次和第三次调用并不像官网说的那样会报错,而是正常执行,不理解为什么会产生这样的情况,我的测试环境是php 5.2.12,哪位同学指点一下。
有一种情况有些特殊,如$b = &$a; $b = 3; var_dump($a);
,$a的值为3,当赋值,参数传递或返回一个未定义变量的引用时,系统会自动创建该变量。
好,最后再来看一段代码,作个总结,
class A { var $x = 1; } $a = new A; $b = &$a; $c = $a; $a->x = 10; var_dump($b); // object(A)#1 (1) { ["x"]=>int(10) } var_dump($c); // object(A)#1 (1) { ["x"]=>int(10) } $a = array(1); var_dump($b); // array(1) { [0]=>int(1) } var_dump($c); // object(A)#1 (1) { ["x"]=>int(10) } $c = $a; $a[0] = 10; var_dump($b); // array(1) { [0]=>int(10) } var_dump($c); // array(1) { [0]=>int(1) },$b是$a的引用,而$c是$a直接赋值,一开始$a指向A的一个对象,因此赋值给$c的是对象地址,所以第一次改动,$b和$c都会相应变化。 接下来,$a是一个数组,赋值给$c的时候采用了值传递,因此$a的改动不会影响到$c。