php基础

先花一分钟看看常见符号和函数: http://www.chinaz.com/program/2010/0331/110317.shtml

 

echo和print的区别

PHP 和 HTML 最简单的交互是通过 print 和 echo 语句来实现的,在实际使用中, print 和 echo 两者的功能几乎是完全一样。可以这么说,凡是有一个可以使用的地方,另一个也可以使用。但是,两者之间也还是一个非常重要的区别:在 echo 函数中,可以同时输出多个字符串,而在 print 函数中则只可以同时输出一个字符串。同时,echo函数并不需要圆括号,所以echo函数更像是语句而不像是函数。

echo 和 print 都不是函数,而是语言结构,所以圆括号都不是必需的。他们的区别在于:
(1) echo可以输出多个字符串,像下面这样:
echo 'a','b','c';
如果你非要加上圆括号,注意写成echo ('a','b','c');是错误的,应该写成:
echo ('a'),('b'),('c');
它没有像函数的行为,所以不能用于函数的上下文
(2) print只能输出一个字符串,它可以表现得像一个函数,比如你可以如下使用:
$ret = print 'Hello World';
所有它能用在更复杂的表达式中。
另外,echo的效率相对比较快~

如下代码:

<?php
$a='hello ';$b='php world!';echo $a,$b.'<br />';//echo 可以用逗号分隔字符串变量来显示print $a.$b.'<br />';//而print不能使用逗号,只能用点号分隔,print $a,$b.'<br />';//使用逗号时报错。
?>

echo    命令和    print    命令    相同,没有区别  
echo    函数    和    print    函数    有区别。  
echo()    无返回值,与echo    命令相同  
print()    有返回值,成功,返1,false,返0.    
printf()    和    sprintf()    类似,均为格式化输出,不同的是前者输出到标准输出,后者输出到变量  
形如  
echo    <<<    EOT  
EOT;  
print    <<<    EOT  
EOT;  
的书写格式,其含义如下:  
<<<    运算符,将由自定义分界符间的内容视为字符串,可对其间的变量做处理  
EOT    自定义分界符,结束时必须位于行首

传址与传值:

$a = 1;
function go(&$b) {
 $b = $b + 1;
}
go($a);
echo $a;
========系统输出2,因为函数直接修改了$a的数值

$a = 1;
function go($b) {
 $b = $b + 1;
}
go($a);
echo $a;
=========系统输出1,因为$b = $b + 1只是在函数内部修改,外部不生效

 

global变量解析

1:Global的作用是定义全局变量,但是这个全局变量不是应用于整个网站,而是应用于当前页面,包括include或require的所有文件

$a=123;

function aa()

{

Global $a;  //如果不把$a定义为global变量,函数体内是不能访问$a的

echo $a;

}

aa();

总结:在函数体内定义的global变量,函数体外可以使用,在函数体外定义的global变量不能在函数体内使用,

global $a;

$a=123;

function f()

{

  echo $a;   //错误,

}

//再看看下面一例

function f()

{

   global $a;

   $a=123;

}

f();

echo $a;  //正确,可以使用

2:global问题解析:

question:我在config.inc.php中定义了一些变量($a),在别的文件中函数外部 include("config.inc.php"),函数内部需要使用这些变量$a,如果没有声明的话,echo $a是打印不出来任何东西的。因此声明global $a,但是有很多函数和很多变量,总不能不断重复的这样声明吧?有什么好的解决办法,请指点。

answer1:先在config.inc.php里定义常量:define(常量名,常量值)

再在其他需要用到的地方require 'config.inc.php',

然后就能在这个文件里直接使用这个常量了。

answer2:我也有个办法,就是定义数组,如$x[a],$x,那样就只要声明global $x一个了。

answer3:我试了你的这个方法,不行啊。

answer4:改你的php.ini文件。

设置global 为 on

 

同javascript一样,php也没有块级作用域的概念。

static变量 是针对于函数内部的来说。

require_once 放在类中的方法中,那么被包含的php中按照require_once的文档(详细是在include中解释的)是继承调用处的变量范围的,也就是类方法范围,因此对$this的引用是可以的,但是其中定义的方法和类是全局的。

 

@的作用:

先做个试验:

$a = 2/0;

你会看到一个错误提示:Warning: Division by zero in ……

@ $a = 2/0;

我们看不到任何提示。

加上@就是为了抑制错误显示,让用户看不到,提升用户体验。注意:只是抑制错误,但是错误还是存在的。

那我们来个友好点的提示吧。

@ $a = 2/0;
if(!$a){
	echo "0不能作为被除数";
}

大括号的使用:

http://hi.baidu.com/%CB%AF%C3%CE%D6%AE%C1%FA/blog/item/3d8b5818b9923fac4bedbcf1.html

1、正确的写法为:${var} 的形式;

2、与双引号一同使用;

例如

<?php
echo <<<EOT
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;
?>

输出为:

My name is "MyName". I am printing some Foo. Now, I am printing some Bar2. This should print a capital 'A': A

3、根据需表达的意思进行定界。

所以,最后我把switch一行改为:

switch ("${action}_${child}") {

即不再出现Notice警告。

4:等同于java的charAt

<?php
$s = "123456";

echo $s{0};	//普通使用
echo "{$s{0}}"; //在双引号中的使用
?>

 

try catch

       try catch 只能捕获面向对象后的Exception,这个Exception是要抛出来才有,要捕获编译错误之类的还要处理一下,见ErrorException:

<?php
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

/* Trigger exception */
strpos();
?> 

 

使用&&,|| 而不是 and or

|| && 的优先级比 or and 高,并且 = 的优先级比 or and 高, and xor or , 的优先级比=低

bool型转换

当转换为 boolean 时,以下值被认为是 FALSE

因此,使用!$obj 与 isset($obj)还是有区别的,后者只判断是否是null或不存在,而前者将空数组,空字符串也认为是false了,这个与javascript是不同的。

 

名空间5.3才开始支持

匿名函数,闭包5.2支持的还不好,不推荐使用.
如果子类中定义了构造函数则不会暗中调用其父类的构造函数.
函数默认是public 全局
范围解析操作符(也可称作 Paamayim Nekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员、方法和常量,还可以用于覆盖类中的成员和方法。对于parent::它表示访问父类实例方法而不是静态方法.
对于self::表示访问类方法(静态,常量等),$this->表示对象本身指针。

就像其它所有的PHP静态变量一样,静态属性只能被初始化为一个字符值或一个常量,不能使用表达式。

常量是替换define的功能的,

5.1开始支持函数参数类型声明 Type Hinting

===对象比较

==值比较

array和javascript array一样是多种类型的混合体(array,map,queue)

 

在函数原型中,$... 表示等等的意思。当一个函数可以接受任意个参数时使用此变量名。//[伪类型类型最后一段]这句话不知什么意思,实践行不通

支持不定参数,但是与java不同,object[]不作为不定参数集合看待而仅仅指代一个参数。
支持三元运算符。
php4 用var定义属性,php5使用访问限制,不需要var
支持自动类型转换
if (null){} 与if (false){}等效.

 

switch可以判断基础类型 int ,string

关于路径的问题,网上出现很多问题,但是其实只要分清楚页面php和类库php就好说了

对于类库文件包含引用(使用的类,相当于java的import),就是用包名形式,不要以/开始,而是直接的包名开头,例如"Zend/Log/Log.php"
对于页面文件,如果不是包含页面的而是使用类的话,也和上面一样。

 

我几乎没用过包含页面的形式(类似于jsp里面的include指令),也不打算在php里面用,所以很简单。(php引用原理我贴了一篇文章)

 

在打日志是出现日期警告(5.3.0以后),需要在php.ini里面配置一下。
php.ini
http://php.net/date.timezone
date.timezone = America/New_York

自定义打开文件夹工具(myeclipse自带有):

Run–>External Tools–>Open External Tools Dialog…

new 一个 program

location 里面填 :C:\WINDOWS\explorer.exe

Arguments 里面填: ${container_loc}

 

zend 文档 chm pdf格式在http://mikaelkael.fr中可以找到

 

MySQL问题

php执行sql操作如果sql有问题,那是什么错误也没报的,这点很晕!

你可以使用mysql_error和mysql_errno来获得错误信息。

也可对mysql进行监视:

有时我们使用了PHP框架,然后使用现成的ORM,省去了写SQL的麻烦,但又想看看到底生成了哪些SQL;或者下载了wordpress或druapl,想看看人家的SQL是怎么写的,这时如果能够监视MySQL的一举一动就好了,也不难,只需要稍微配置一下,再加上一个工具就行了。

首先,打开%MySQLDir%my.ini(linux下是my.cnf)加上这么一句

# 指定log的位置
log=C:/AppServ/MySQL/mysql.log
# 或者linux下 log=/var/log/mysql/mysql.log

 

mysql_*函数是没有事务的,你可以自己写sql语句来实现:

function db_trans_begin(){
	getlink();
	mysql_query( "SET AUTOCOMMIT=0");
	mysql_query( "BEGIN");
}

function db_trans_commit(){
	mysql_query( "COMMIT");	
	mysql_query( "SET AUTOCOMMIT=1");
}

function db_tans_rollback(){
	mysql_query("ROOLBACK");
	mysql_query( "SET AUTOCOMMIT=1");
}

mysqli就有这些方法了。

 

 

php5以后mysql不是默认支持的,需要在php.ini中将

extension_dir配置正确

extension=php_mysql.dll
extension=php_pdo_mysql.dll [如果使用pdo]

这2行去掉注释。

 

使用zend db取的数据后,

 

php框架:
yii 不支持php4 性能据说很好 还有中文文档
cake 支持php4
zend 不支持php4 而且太大了压缩包20m 但是是官方框架(但是也有成为java的EJB的可能,我是说好听不好用)

国内的不考虑,据说是吹牛。

 

乱码问题,除了其他情况,mysql连接要设置连接字符集
// 方法一:
PDO::__construct($dsn, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8';"));
 
// 方法二:
PDO::__construct($dsn, $user, $pass);
PDO::exec("SET NAMES 'utf8';");

 

$arr = array(-10=>'1');

$arr[]='2'; //负数索引之后在默认添加的是索引0

echo $arr[0]; //输出2

 

php理念是一个页面运行完后所有对象回收,所以想要对象跨页面就比较困难,

例如下面的讨论情况:

我想将用户信息实例化成一个对象,借此减少需要用户信息的时候读取数据库的次数

这样有必要吗?

OK~如果有必要那么

跨页面传递对象除了序列化还有其他方法吗?   

在安装memcache等内存缓存服务前,所有程序对象和session对象是通过序列化来存贮的。 PHP具有强大的数组支持,把数据存到特定的数组中(如,$_SESSION),会是一个不错的选择。但也要避免把所有的数据都存入Session,因为$_SESSION在每次的HTTP REQUEST处理中都会被装载,太大的$_SESSION数组会对系统性能产生影响。

使用对象来存贮信息,再保存到$_SESSION数组中序列化是正常的操作,特定情况下要注意对象的设计来保证对象的序列化的正常,有时会用到对象的__sleep和__wakeup方法。

以上是server端传递对象的方法。对于简单的数据信息,可以在客户端完成跨页面传递:

* GET方法 通过URL;

* POST 方法 <input type="hidden" >

* JavaScript:document 下的子节点 (时尚做法,但要考虑更多安全性)

 

这样的局限性导致要实现基于xmpp的即时通信比较麻烦,因为不知道在哪里保存xmpp connection?使用长连接倒是可以。

 

php给我的感觉就是,适合做web UI部分,再利用数据库展示ui方面有优势。但是如果要做复杂的应用则不合适,因为:

第三方库乱七八糟,

语言本身决定xmpp就是个好例子。

 

我的想法:

php + 数据库->展示UI,其他的复杂的交由别的来做(java/c)


Total views.

© 2013 - 2024. All rights reserved.

Powered by Hydejack v6.6.1