php易混淆知识点

1、define(“constant”,  “hello world”);和const constant = “hello world”;的区别?javascript

(0).使用const使得代码简单易读,const自己就是一个语言结构,而define是一个函数。另外const在编译时要比define快不少。php

(1).const用于类成员(或者接口成员)变量的定义,一经定义,不可修改。php5.3以上支持类外经过const定义常量,而且在使用命名空间时只能用这个来定义常量. define不可用于类成员变量的定义,可用于全局常量。html

好比:
one.php
<?php
namespace test;
const AA= 'AA'; 
define('BB','BB');
?>
two.php
<?php
include_once('one.php');
echo \test\AA; //正确
echo \test\ BB;//错误


const DEFINES='tt';
define('DEFINES','ccdec');

?>

file1.phpjava

<?php
const DEFINES = 1;
define('DEFINES','ccc');
echo DEFINES;  
?>

结果://Notice: Constant DEFINES already defined 输出为1,但最后的值以第一个定义的为准
说明在命名空间以外const与define定义常量的做用是同样的
mysql

(2).const可在类中使用,define不能。android

(3).const不能在条件语句中定义常量。ios

例如: c++

if (...){ 

  const FOO = 'BAR';  // 无效的invalid 

}  

if (...) { 

  define('FOO', 'BAR'); // 有效的valid 

}

(4).const采用一个普通的常量名称,define能够采用表达式做为名称。 web

 const  FOO = 'BAR';  

 for ($i = 0; $i < 32; ++$i) { 

  define('BIT_' . $i, 1 << $i); 

} 

(5).const只能接受静态的标量,而define能够采用任何表达式。正则表达式

例如: 

const BIT_5 = 1 << 5;  // 无效的invalid  

define('BIT_5', 1 << 5); // 有效的valid

(6).const定义的常量时大小写敏感的,而define可经过第三个参数(为true表示大小写不敏感)来指定大小写是否敏感。

例如:

define('FOO', 'BAR', true);  

echo FOO; // BAR 

echo foo; // BAR

二:php中int的范围?32位系统和64位系统是否有区别?为何?php数据入库前清理,注意php intval与mysql的int取值范围不一样。

php中int的范围

整型值可使用十进制,十六进制,八进制或二进制表示,前面能够加上可选的符号(- 或者 +)。

二进制表达的 integer 自 PHP 5.4.0 起可用。

要使用八进制表达,数字前必须加上 0(零)。要使用十六进制表达,数字前必须加上 0x。要使用二进制表达,数字前必须加上 0b

注意:

整型数的字长和平台有关,尽管一般最大值是大约二十亿(32 位有符号)。64 位平台下的最大值一般是大约 9E18。PHP 不支持无符号整数。Integer 值的字长能够用常量 PHP_INT_SIZE来表示,自 PHP 4.4.0 和 PHP 5.0.5后,最大值能够用常量 PHP_INT_MAX 来表示。

所谓32位处理器就是一次只能处理32位,也就是4个字节的数据,而64位处理器一次就能处理64位,即8个字节的数据。
学过计算机组成原理的都知道32处理器具备32根数据线,一个存取周期能够经过这32根数据线读取32bit的数据(每根传输1bit),也就是4字节,同理在64位处理器在一个存取周期可以处理8字节数据。
unsigned int在64位系统中使用8个字节表示,表示的数值范围0~2^64-1,也就是说64位系统较32位系统可以表示更大的数值,unsigned int在64位系统中占用8个字节的好处:一是方便存取,二是可以表示更大数值范围。

1.64bit CPU拥有更大的寻址能力,最大支持到16GB内存,而32bit只支持4G内存 
2.64位CPU一次可提取64位数据,比32位提升了一倍,理论上性能会提高1倍。但这是创建在64bit操做系统,64bit软件的基础上的。
名词解释:什么是64位处理器 
之因此叫作“64位处理器”,是由于电脑内部都是实行2进制运算,处理器(CPU)一次处理数据的能力也是2的倍数。8位处理器、16位处理器、32位处理器和64位处理器,其计数都是2的倍数。一次处理的数据越大,该电脑处理信息的能力愈来愈大;所以64位处理在先天就比32位处理器具备快速的能力。那为何不用更高级的128位处理器呢?由于位数越高,处理器芯片的设计也就越复杂,目前的技术水平暂时没法制造这么复杂的芯片。

参考:http://bbs.csdn.net/topics/390191926

整数溢出

若是给定的一个数超出了 integer 的范围,将会被解释为 float。一样若是执行的运算结果超出了 integer 范围,也会返回 float

Example #3 32 位系统下的整数溢出
<?php
$large_number = 2147483647;
var_dump($large_number);                     // int(2147483647)

$large_number = 2147483648;
var_dump($large_number);                     // float(2147483648)

$million = 1000000;
$large_number =  50000 * $million;
var_dump($large_number);                     // float(50000000000)
?>
Example #4 64 位系统下的整数溢出
<?php
$large_number = 9223372036854775807;
var_dump($large_number);                     // int(9223372036854775807)

$large_number = 9223372036854775808;
var_dump($large_number);                     // float(9.2233720368548E+18)

$million = 1000000;
$large_number =  50000000000000 * $million;
var_dump($large_number);                     // float(5.0E+19)
?>

PHP 中没有整除的运算符。1/2 产生出 float 0.5。值能够舍弃小数部分强制转换为 integer,或者使用 round() 函数能够更好地进行四舍五入。

<?php
var_dump(25/7);         // float(3.5714285714286) 
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7));  // float(4) 
?>

浮点型转换

当从浮点数转换成整数时,将向下取整。

若是浮点数超出了整数范围(32 位平台下一般为 +/- 2.15e+9 = 2^31,64 位平台下一般为 +/- 9.22e+18 = 2^63),则结果为未定义,由于没有足够的精度给出一个确切的整数结果。在此状况下没有警告,甚至没有任何通知!

 

32位、64位对api的影响:Andriod、iOS、JavaScript等

常见操做系统:

Android:只有32位

iOS:只有32位

Linux server(CentOS、Ubuntu、RedHat等):64位(大部分公司服务器使用)、32位(已淘汰)

Windows PC:64位,32位

常见软件:

Android app:java或c++。若是用java,os无关,则int是64位。若是用c++,待验证。

iOS app:object c,os有关。int是32位。

php:os有关。编译安装与server相同,int为64位或32位。

mysql:os无关。int为64位。

32位浏览器(chrome、firefox)中的JavaScript:约9千万亿,待定,未找到权威文档

64位浏览器(waterfox)中的JavaScript:约9千万亿,待定,未找到权威文档

var a = 9000000000000001;alert(a -1 + 1);

对api程序开发的影响:

经过php开发api提供json给app、浏览器js引擎使用时,因为php的web server是64位的,而Android、iOS、浏览器js的int范围不一致。

32位int大概为21亿,好比网盘的用户总容量为5GiB,php接口返回数据以下:

{

    "capacity" : 5368709120, //容量53亿Byte,即5GiB,超过了21亿

    "used_space" : 1073741824

}

结果:Android Java app正常,iOS app没法处理数据,浏览器JavaScript正常。

因此须要使用string,而不是int,iOS拿到以后再作大整数相除便可。即:

{

    "capacity" : "5368709120",

    "used_space" : "1073741824"

}

PHP 中的整数是 C 语言的中的long 类型,是有符号的,最大值是 2^31 。在 64 位平台上,long能够达到 2^63.

这样的话,有些PHP 函数输出的结果在各个平台上就会不一致了。

php -r "echo ip2long('255.255.255.255');" 在64位平台下是: 4294967295, 在32位平台下是 -1。还有好比 filesize 在 文件 大于 2G的时候,在不一样的平台下结果就不一致了。

解决这个问题很简单,sprintf("%u", filesize($file)). 把结果转换为 一个字符串。为何结果会同样呢:无符号数 4294967295 的补码 和 有符号数 -1 的补码 是同样的。相似,返回值为int 最后结果可能大于 2^31 的函数,都要用这样的方法处理。

注意,返回的虽然是一个字符串,可是,当进行四则运算的时候,PHP会自动装换。若是 数大于 2^31 会转换为 int 若是大于 了,就转换为double。

参考:32位和64位系统区别及int字节数  http://blog.csdn.net/zhongzhiwei/article/details/8678885

php数据入库前清理,注意php intval与mysql的int取值范围不一样

php intval的取值范围与mysql的int类型同样吗? 
查了一下,不同…… 
http://php.net/manual/en/function.intval.php
http://dev.mysql.com/doc/refman/5.1/zh/column-types.html#numeric-types
php intval的取值范围:与操做系统相关,32位系统上为-2147483648到2147483647,64位系统上为-9223372036854775808到9223372036854775807。 
mysql int取值范围:与操做系统无关,为-2147483648到2147483647,无符号为0到4294967295。 
mysql bigint取值范围:与操做系统无关,为-9223372036854775808到9223372036854775807,无符号为0到18446744073709551615。

3、php下intval()和(int)转换使用与区别

int intval ( mixed $var [, int $base ] )

没啥区别,通常用(int),另外还有 float, string, array等
intval()而言,若是参数是字符串,则返回字符串中第一个不是数字的字符以前的数字串所表明的整数值。若是字符串第一个是‘-',则从第二个开始算起。若是参数是符点数,则返回他取整以后的值。
当intval()返回的值在一个4字节所能表示的范围以内(-2147483648~2147483647),对于超过这个范围的值将用边界值代替。 

例:intval("A")=0; intval(12.3223)=12; intval("1123Asdfka3243")=1123; 
int(); 
例: 
$a=0.13; 
$b=(int)$a; //$b=0; 

$a=0.99; 
$b=(int)$a; //$b=0; 

$a=1.01; 
$b=(int)$a; //$b=1; 

$a=1.99; 
$b=(int)$a; //$b=1;

 

PHP中intval()等int转换时的意外异常状况解析

$a = 9.45*100;  
var_dump($a);  
var_dump(intval($a));  
  
$a = 945*1.00;  
var_dump($a);  
var_dump(intval($a)); 

运行结果:float(945) int(944) float(945) int(945

缘由解释:

这个代码虽然把结果都告诉了,可是不少人仍是看不懂,这样就解释不了为何会有意想不到的转型状况发生。

网上对这个状况讲的都模棱两可不知所云的。我在这里简单的解释下:

9.45这个数字在咱们看到的是这样的,可是机器内部却不是这个,而是9.44999999999999999...。因此:

9.449999*100 = 944.9999。这样就能够看懂了吧?intval把尾数直接去掉了,这个叫神马来的呵呵忘了名字了.这样说来,intval和floor()函数差很少咯。呵呵。这个也是我以前没有察觉到的。也没注意到intval会向下舍入。

而 1.00就没有什么1.0099999这样的了,因此945*1.00就会出现一个float的945.那intval去转型天然就不会出现944的状况了。

还有些经典考试题,如:intval((0.1+0.7)*10) 等于7而不是8的。都是这个道理。

参考:http://www.php.net/manual/zh/language.types.float.php#warn.float-precision

4、什么是静态变量?适用的状况是?优势和缺点分别是什么?

静态变量是指用static声明的变量,这种变量与局部变量的区别是,当静态变量离开了它的做用范围后,它的值不会自动消亡,而是继续存在,当下次再用到它的时候,能够保留最近一次的值。

<?php
function add() 
{ 
    static $i=0; 
    $i++; 
    echo $i; 
} 
add(); 
echo " "; 
add(); 
?>

静态变量的好处: 持有对象,对于运行时的常量和须要缓存的数据是很重要的。
坏处:整个应用的生命周期内一直占用资源,例如web应用每一次登陆在static map cache中记录一个数据,而不(按期)清除。那么时间一长,这个东西很是大。
对于缓存的数据,若是运行时发生变化须要考虑同步操做带来的并发问题。

1  静态局部变量在静态存储区内分配存储单元。在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,存储在动态存储区空间(而不是静态存储区空间),函数调用结束后即释放。 
2 为静态局部变量赋初值是在编译时进行值的,即只赋初值一次,在程序运行时它已有初值。之后每次调用函数时再也不从新赋初值而只是保留上次函数调用结束时 的值。而为自动变量赋初值,不是在编译时进行的,而是在函数调用时进行,每调用一次函数从新给一次初值,至关于执行一次赋值语句 
3 若是在定义局部变量时不赋初值的话,对静态局部变量来讲,编译时自动赋初值0(对数值型变量)或空字符(对字符型变量)。而对自动变量来讲,若是不赋 初值,则它的值是一个不肯定的值。这是因为每次函数调用结束后存储单元已释放,下次调用时又从新另分配存储单元,而所分配的单元中的值是不肯定的。 
4 虽然静态局部变量在函数调用结束后仍然存在,但其余函数是不能引用它的,也就是说,在其余函数中它是“不可见”的。

5、include,include_once,require,require_once的区别?

6、dl函数的用途,什么状况下不能使用?如何得到当前进程id?如何得到当前文件include文件列表?当php作为命令行运行时容易超时退出,如何延长运行时间?

6、string get_cfg_var ( string $option ) 与 ini_get() 的区别
get_cfg_var returns the value from php.ini directly,while the ini_get returns   the runtime config value. I have tried it on PHP 5.1.6 

[EDIT by danbrown AT php DOT net: The author of this note means that ini_get() will return values set by ini_set(), .htaccess, a local php.ini file, and other functions at runtime.  Conversely, get_cfg_var() will return strictly the server php.ini.]

 

7、php中getenv()和$_SERVER的区别

  两者的区别在于,getenv不支持IIS的isapi方式运行的php

 

8、获取php运行信息

int getmypid ( void )  返回当前 PHP 进程 ID,或在错误时返回 FALSE 如:查看进程管理器发现对应的映像名称为httpd.exe

int getmygid ( void ) 返回当前 PHP 脚本拥有者的用户组 ID,或在错误时返回 FALSE

int getmyuid ( void ) 返回当前脚本的用户 ID,或在错误时返回 FALSE

string get_current_user ( void ) 返回当前 PHP 脚本全部者名称。

string php_sapi_name ( void ) 返回描述 PHP 所使用的接口类型(the Server API, SAPI)的小写字符串。 例如,CLI 的 PHP 下这个字符串会是 "cli",Apache 下可能会有几个不一样的值,取决于具体使用的 SAPI。 如下列出了可能的值。

 

9、php是否支持多线程?

PHP语言自己是不支持多线程的. 总结了一下网上关于PHP模拟多线程的方法, 总的来讲, 都是利用了PHP的好伙伴们自己所具备的多线程能力. PHP的好伙伴指的就是LINUX和APACHE啦, LAMP嘛.另外, 既然是模拟的, 就不是真正的多线程. 其实只是多进程. 进程和线程是两个不一样的概念. 好了, 如下方法都是从网上找来的.

咱们知道php(作为如今的主流开发语言)自己是不支持多线程的, 可是咱们的WEB服务器是支持多线程的.也就是说能够同时让多人一块儿访问. 这也是我在php(作为如今的主流开发语言)中实现多线程的基础.

假设咱们如今运行的是a.php(作为如今的主流开发语言)这个文件. 可是我在程序中又请求WEB服务器运行另外一个b.php(作为如今的主流开发语言)那么这两个文件将是同时执行的.


1. 利用LINUX操做系统
<?php
for ($i=0;$i<10;$i++) {
  echo $i;
  sleep(5);
}
?>
上面存成test.php, 而后写一段SHELL代码

#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9 10
do
php -q test.php &
done

2. 利用fork子进程(其实一样是利用LINUX操做系统)

<?php
declare(ticks=1);
$bWaitFlag = FALSE; /// 是否等待进程结束
$intNum = 10;      /// 进程总数
$pids = array();    /// 进程PID数组
echo ("Startn");
for($i = 0; $i < $intNum; $i++) {
 $pids[$i] = pcntl_fork();/// 产生子进程,并且从当前行之下开试运行代码,并且不继承父进程的数据信息
 if(!$pids[$i]) {
  // 子进程进程代码段_Start
  $str="";
  sleep(5+$i);
  for ($j=0;$j<$i;$j++) {$str.="*";}
  echo "$i -> " . time() . " $str n";
  exit();
  // 子进程进程代码段_End
 }
}
if ($bWaitFlag)
{
 for($i = 0; $i < $intNum; $i++) {
  pcntl_waitpid($pids[$i], $status, WUNTRACED);
  echo "wait $i -> " . time() . "n";
 }
}
echo ("Endn");
?>

 

3. 利用WEB SERVER, PHP不支持多线程, APACHE但是支持的,  假设咱们如今运行的是a.php这个文档. 可是我在程式中又请求WEB服务器运行另外一个b.php那么这两个文档将是同时执行的.
<?php
function runThread()()
{
 $fp = fsockopen('localhost', 80, $errno, $errmsg);
 fputs($fp, "GET /a.php?act=brnrn");
 fclose($fp);
}
function a()
{
 $fp = fopen('result_a.log', 'w');
 fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
 fclose($fp);
}
function b()
{
 $fp = fopen('result_b.log', 'w');
 fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
 fclose($fp);
}
if(!isset($_GET['act'])) $_GET['act'] = 'a';
if($_GET['act'] == 'a')
{
 runThread()();
 a();
}
else if($_GET['act'] == 'b') b();
?>

固然啦,也能够把须要多线程处理的部分交给JAVA去处理, 而后在PHP里调用, 哈哈.

<?php
system('java multiThread().java');
?>

进程和线程的区别  http://www.cnblogs.com/lmule/archive/2010/08/18/1802774.html

 

 

10、php如何管理内存?

PHP的内存管理    http://www.nowamagic.net/librarys/veda/detail/1440

PHP原理以内存管理中难懂的几个点   http://www.laruence.com/2011/11/09/2277.html

深刻理解PHP内存管理之谁动了个人内存  http://www.laruence.com/2011/03/04/1894.html

深刻理解PHP内存管理之一个低几率Core的分析  http://www.laruence.com/2011/01/27/1854.html

深刻探讨PHP中的内存管理问题    http://www.jb51.net/article/28166.htm

 

10、php获取当前文件所在的目录(getcwd和dirname(__FILE__)的区别)

经过dirname(__FILE__)得到当前文件所在的目录.

 <?php
/**
__FILE__ ,
getcwd(),
$_SERVER["REQUEST_URI"],
$_SERVER["SCRIPT_NAME"],
$_SERVER["PHP_SELF"],
$_SERVER["SCRIPT_FILENAME"],

来观察一下这些变量或函数的异同.
假设有一个请求地址为: http://localhost:8080/test.php/age=20
而test.php 的完整路径是: D:/server/www/example/test.php
1) getcwd()
将获得浏览器请求的页面文件所在的目录. 即test.php 文件所在的目录: D:/server/www/example/ ,
若是在test.php 执行了 require 或 include 语句, 好比 inculde(”test_dir/test2.php”),

那么在 test2.php 里 getcwd()函数 返回的也将是 test.php 所在的目录.

与$_SERVER['DOCUMENT_ROOT']的值相同,只是路径分隔符不一样,getcwd()为\,$_SERVER['DOCUMENT_ROOT']为/。

2) __FILE__
一个魔术变量, 用它将获得 __FILE__ 变量所在文件的完整路径,
好比: test.php 里 __FILE__ 将获得 D:/server/www/example/test.php ,

test_dir/test2.php 里的 __FILE__ 将获得 D:/server/www/example/test_dir/test2.php


与$_SERVER['SCRIPT_FILENAME']返回的值相同,只是路径分隔符不一样,__FILE__返回的路径分隔符是\,$_SERVER['SCRIPT_FILENAME']返回的值的路径分隔符是/


3) $_SERVER["SCRIPT_FILENAME"]
将获得浏览器请求的页面文件的完整路径.
test.php 和 test_dir/test2.php 里用 $_SERVER["SCRIPT_NAME"] 都将获得 D:/server/www/example/test.php.

4) $_SERVER["SCRIPT_NAME"]
将获得浏览器请求的页面文件的文件名,注意: 与 $_SERVER["SCRIPT_NAME"] 不一样, 此变量只获得文件名而不包含路径,
在test.php 与 test_dir/test2.php 用$_SERVER["SCRIPT_NAME"] 获得的都将是 test.php.
固然, 在test.php 与 test_dir/test2.php 执行 basename($_SERVER["SCRIPT_FILENAME"]) 与 $_SERVER["SCRIPT_NAME"] 相同.
执行 在test.php 与 test_dir/test2.php 执行 realpath(”test.php”) 获得的结果与 $_SERVER["SCRIPT_FILENAME"] 相同.

5) $_SERVER["PHP_SELF"]
将获得浏览器请求页面的文件名, 并剥掉问号 ? 后的内容, 注意:不包含路径,
好比在客户端里请求 http://localhost:8080/test.php?age=20&name=Tom,
那么test.php 和 test_dir/test2.php 的 $_SERVER["PHP_SELF"] 都将获得 “test.php”。“age=20&name=Tom”被剥掉。
而若是客户端里请求 http://localhost:8080/test.php/age=20&name=Tom,

那么test.php 和 test_dir/test2.php 的 $_SERVER["PHP_SELF"] 都将获得 “test.php/age=20&name=Tom”。

 

$_SERVER['PHP_SELFT']与$_SERVER['SCRIPT_NAME']和$_SERVER['REQUEST_URI']和$_SERVER['QUERY_STRING']的区别:
http://localhost:60/phptour/test/test7.php/a=b
$_SERVER['PHP_SELF']将获得:/phptour/test/test7.php/a=b
$_SERVER['SCRIPT_NAME']将获得:/phptour/test/test7.php
$_SERVER['REQUEST_URI']将获得:/phptour/test/test7.php/a=b
$_SERVER['QUERY_STRING']将获得:''

http://localhost:60/phptour/test/test7.php?a=b
$_SERVER['PHP_SELF']与$_SERVER['SCRIPT_NAME']都将获得:/phptour/test/test7.php
$_SERVER['REQUEST_URI']将获得:/phptour/test/test7.php?a=b
$_SERVER['QUERY_STRING']将获得:a=b
总结:$_SERVER['PHP_SELF']会返回/phptour/test7.php/a=b,会返回文件名/后面的内容
            $_SERVER['SCRIPT_NAME']只会返回/phptour/test.php,不会返回文件名后面的/后面的内容
 

6) $_SERVER["REQUEST_URI"]
将获得浏览器请求页面的文件名, 以及文件名以后的全部内容(注意: 井号 # 以后的内容将被略去),
好比在客户端里请求 http://localhost:8080/test.php?age=20&name=Tom,
那么test.php 和 test_dir/test2.php 的 $_SERVER["REUEST_URI"] 都将获得 “test.php”。“age=20&name=Tom”被剥掉。
而若是客户端里请求 http://localhost:8080/test.php/age=20&name=Tom,
那么test.php 和 test_dir/test2.php 的 $_SERVER["REQUEST_URI"] 都将获得 “test.php/age=20&name=Tom”。
*/

7) $_SERVER["QUERY_STRING"]
将获得查询的字符串(?后面的字符串)

 

//test.php:
echo“test1.php variables<br/>”;
echo“getcwd:“,getcwd(),“<br/>”;
echo“__FILE__:“,__FILE__,“<br/>”;
echo“REQUEST_URI:“,$_SERVER["REQUEST_URI"],“<br/>”;
echo“SCRIPT_NAME:“,$_SERVER["SCRIPT_NAME"],“<br/>”;
echo“PHP_SELF:“,$_SERVER["PHP_SELF"],“<br/>”;
echo“SCRIPT_FILENAME “,$_SERVER["SCRIPT_FILENAME"],“<br/>”;

//把 test2.php 包含进来, 在 test2.php 里输出上面的变量,看有什么不一样:
include_once(”test2/test2.php”);

?>

总结:$_SERVER[]返回值中的路径分隔符都是/斜线,__FILE__,getcwd(),返回值的路径分隔符为\反斜线。

 

 11、自动加载函数__autoload() 和spl_autoload

 php的autoload大体可使用两种方法:__autoload和spl方法。这两种方法又各有不一样的几种使用方法

__autoload的使用方法1:
最常用的就是这种方法,根据类名,找出类文件,而后require_one

复制代码 代码以下:

function __autoload($class_name) {
$path = str_replace('_', '/', $class_name);
require_once $path . '.php';
}
// 这里会自动加载Http/File/Interface.php 文件
$a = new Http_File_Interface();


这种方法的好处就是简单易使用。固然也有缺点,缺点就是将类名和文件路径强制作了约定,当修改文件结构的时候,就势必要修改类名。

__autoload的使用方法2(直接映射法)

复制代码 代码以下:

$map = array(
'Http_File_Interface' => 'C:/PHP/HTTP/FILE/Interface.php'
);
function __autoload($class_name) {
if (isset($map[$class_name])) {
require_once $map[$class_name];
}
}
// 这里会自动加载C:/PHP/HTTP/FILE/Interface.php 文件
$a = new Http_File_Interface();


这种方法的好处就是类名和文件路径只是用一个映射来维护,因此当文件结构改变的时候,不须要修改类名,只须要将映射中对应的项修改就行了。

这种方法相较于前面的方法缺点是当文件多了的时候这个映射维护起来很是麻烦,或许这时候你就会考虑使用json或者单独一个文件来进行维护了。或许你会想到使用一个框架来维护或者创建这么一个映射。

spl_autoload

__autoload的最大缺陷是没法有多个autoload方法

好了, 想下下面的这个情景,你的项目引用了别人的一个项目,你的项目中有一个__autoload,别人的项目也有一个__autoload,这样两个__autoload就冲突了。解决的办法就是修改__autoload成为一个,这无疑是很是繁琐的。

所以咱们急需使用一个autoload调用堆栈,这样spl的autoload系列函数就出现了。你可使用spl_autoload_register注册多个自定义的autoload函数

若是你的PHP版本大于5.1的话,你就可使用spl_autoload

 

 12、 php中time函数的返回值是?不一样时区,同一时刻返回值是否相同?是否还有其它方法得到与time相同的值?

time() 函数返回当前时间的 Unix 时间戳。即自从 Unix 纪元(格林威治时间 1970 年 1 月 1 日 00:00:00)到当前时间的秒数
Unix时间戳(英文为Unix epoch, Unix time, POSIX time 或 Unix timestamp)
是从1970年1月1日(UTC/GMT的午夜)开始所通过的秒数,不考虑闰秒。
因此time()是不考虑时区的

格林尼治标准时间(GMT):格林尼治标准时间(GMT,旧译“格林威治平均时间”或“格林威治标准时间”)是指位于 伦敦郊区的皇家格林尼治天文台的标准时间,
由于本初子午线被定义在经过那里的经线。理论上来讲,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时 (也就是在格林尼治上空最高点时)的时间。
因为地球在它的椭圆轨道里的运动速度不均匀,这个时刻可能和实际的太阳时相差16分钟。地球天天的自转是有些不 规则的,并且正在缓慢减速。
因此,格林尼治时间已经再也不被做为标准时间使用。
由于php是一门运行在服务器上的语言,因此,若是你在你本身的机器上进行测试的话,time()函数将直接读取你机器的时候,
换算成秒数后,再与1970.1.1 00:00:00做差,得出结果。因此,不管你的时区怎样设置,只要你本地机器时间没有变化,
time()函数返回的结果就不会有变化。在PHP5.1之后,你已经不须要使用time()函数了,直接读取$_SERVER['REQUEST_TIME']就能够获取结果。
<?php   echo time(); ?>
一个放在中国, 执行. 一个和在美国,执行.为何返回的值相差60秒? 也很少, 就100之内.
缘由:PHP5要设置时区,你说的问题很简单,服务器时间不许

1》经过getdate()函数得到的数组中键名为0的值和time()值相同。

2》经过gettimeofday()获取键名为sec的值与time()值相同;

3》经过分解microtime()获得的值也能够得到和time()同样的结果。


十3、dl函数的用途,什么状况下不能使用?如何得到当前进程id?如何得到当前文件include文件列表?当php作为命令行运行时容易超时退出,如何延长运行时间?

官方解释:在php脚本里动态加载php模块,执行结果返回true或者false,默认加载extension_dir目录里的扩展(可指定路径),当 PHP 运行在 安全模式 时,(强制)不能使用此函数。

所谓的隐患就是,php默认开始此函数,而且关闭安全模式,那么用户(攻击者)就能够上传本身编写的恶意模块,并启用他,或者启用php自带可是没被删除只是简单禁用而又有安全隐患的模块。
关闭的方法是:
1,修改php.ini里的enable_dl = On为Off
2,开启安全模式(影响效率,可是安全)
3,加入php.ini的disable_functions里,也能够把其它认为不安全的函数加入,好比 exec,passthru,shell_exec,system,proc_open,popen, curl_exec,curl_multi_exec,parse_ini_file,show_source

dl()动态加载php扩展。安全模式下该函数不能够用。经过getmypid()得到当前进程id。
经过get_included_files()函数得到当前文件include文件列表。php在命令行下执行时,能够经过设置max_execution_time的值来改变运行时间长短。

<?php
// Example loading an extension based on OS
if (!extension_loaded('sqlite')) {
    if (
strtoupper(substr(PHP_OS03)) === 'WIN') {
        
dl('php_sqlite.dll');
    } else {
        
dl('sqlite.so');
    }
}
// Or, the PHP_SHLIB_SUFFIX constant is available as of PHP 4.3.0
if (!extension_loaded('sqlite')) {
    
$prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' '';
    
dl($prefix 'sqlite.' PHP_SHLIB_SUFFIX);
}
?>
十4、mysql和mysqli,pdo的区别?mysql_connect和mysql_pconnect的区别?

参考:php中关于mysqli和mysql区别的一些知识点分析 http://www.jb51.net/article/28103.htm

mysql,mysqli和PDO的区别   http://blog.csdn.net/breeze_life/article/details/8964024

 

mysql_connect 与 mysql_pconnect区别 

创建一个pconnect的链接。而后你去mysql下show processlist,看看,而后再创建几个,再去mysql下show processlist。你会发现有不少死链接处于sleep状态。 当这种状态的数量超过了mysql设置的最大链接数,mysql除了root就谁也连不上了。由于mysql老是会为root留一个位置。 这种长链接只有到达my.cnf里面设置的超时时间后才会自动断开,默认好像是8天吧,忘记了。而后你的mysql error日志中会记录一个warnning,翻译过来就是胎死腹中的链接。 因此说实际开发中,若是你的应用属于多用户的,必定不要使用这种链接。 除非是那种单人应用的系统,任什么时候候都只有一我的链接,那这种长链接方式效率会比短链接更合适。

参考:http://blog.csdn.net/wjc19911118/article/details/7901064

http://hi.baidu.com/shashadu/item/cabf6e790a6a19346cc37c7e

 

十五:如何获得一个字符串中哪一个字符出现的次数最多

 

$str=”asdfgfdas323344##$\$fdsdfg*$**$*$**$$443563536254fas”;//任意长度字符串
 
//解法一(最快速的解法,可是基本功要扎实)
$arr=str_split($str);
$arr=array_count_values($arr);
arsort($arr);
print_r($arr);
 
//解法二(对逻辑能力有必定要求)
$arr=str_split($str);
$con=array();
foreach ($arr as $v){
if (!@$con[$v]){
@$con[$v]=1;
}else{
@$con[$v]++;
}
}
arsort($con);
print_r($con);
//解法三
$arr=str_split($str);
$unique=array_unique($arr);
foreach ($unique as $a){
$arr2[$a]=substr_count($str, $a);
}
arsort($arr2);
print_r($arr2);

 十六:什么是php引用函数

参考:http://sumsung753.blog.163.com/blog/static/146364501201102684942358/

 

 十七:mysql_close($conn) 与 unset($conn) 区别

$conn 链接是一个对某个资源的引用

  • mysql_close($connection) closes the non-persistent connection to the MySQL server that's associated with $connection. If $connection isn't specified, the last opened link is used.

    -this function is deprecated , so please use PDO or mysqli.

  • unset($connection) clears the pointer to the result on php's side, but does not do anything to the result it points to.

 unset($connection) will just make the var $connection equal to NULL. If you didn't do the unset, then the var $connection would still point to a MySQL link identifier, which would be invalid after the mysql_close(). It's a little pedantic; whether you unset or not, the $connection var will not be usable after the mysql_close().

$conn = mysql_connect('localhost', 'root', 'root') or die('connect error:' . mysql_error());
mysql_query("SET NAMES utf8");
mysql_select_db('users', $conn);
var_dump($conn);
echo '<br>';
mysql_close($conn);
var_dump($conn);
exit;

 返回:

resource(3, mysql link)
resource(3, Unknown)
mysql_close只是关闭了拦截,可是$conn这个变量还存在,若是想关闭后销毁变量,能够再mysql_close($conn)后加:unset($conn);
$conn = mysql_connect('localhost', 'root', 'root') or die('connect error:' . mysql_error());
mysql_query("SET NAMES utf8");
mysql_select_db('19youxi', $conn);
unset($conn);
$res = mysql_query("SELECT * FROM users");
var_dump($res);
exit;

 返回:resource(4, mysql result)

可见:虽然在mysql_query以前unset($conn)了,可是并无关闭数据库链接,unset 仅仅是把对应的$conn变量给销毁了

 

十八:什么是php的延迟绑定?

 

十九:写出一个正则表达式,过虑网页上的全部JS/VBS脚本(即把标记及其内容都去掉)

答:/<[^>].*?>.*?<\/>/si

 

20:数组函数 arsort 的做用是(6);语句 error_reporting(2047)的做用是(7)。

:(6)对数组进行逆向排序并保持索引关系  (7)All errors and warnings

21.语句 include 和 require 都能把另一个文件包含到当前文件中,它们的区别是(12);为了不屡次包含同一文件,能够用语句(13)来代替它们。
答:(12) 发生异常时include产生警告require产生致命错误  (13) require_once()/include_once()

22.一个函数的参数不能是对变量的引用,除非在php.ini中把(15)设为on.

答:allow_call_time_pass_reference

23.在PHP中,heredoc是一种特殊的字符串,它的结束标志必须(18)。
答:结束标识符所在的行不能包含任何其它字符除";"

24.echo(),print(),print_r()的区别

答:

echo 和print不是一个函数,是一个语言结构

print(string $arg), 只有一个参数

echo $arg1, $arg2  能够输出多个参数

 

 

echo和print只能打印出string,不能打印出结构

 

print_r能打印出结构, 用于输出数组对象

 

 

25.使用五种以上方式获取一个文件的扩展名

要求:dir/upload.image.jpg,找出 .jpg 或者 jpg ,

答:使用五种以上方式获取一个文件的扩展名

1)
get_ext1($file_name)
{
    return strrchr($file_name, '.');
}

2)
get_ext2($file_name)
{
    return substr($file_name, strrpos($file_name, '.'));
}

3)
get_ext3($file_name)
{

    return array_pop(explode('.', $file_name));

}

4)
get_ext4($file_name)
{
    $p = pathinfo($file_name);
    return $p['extension'];
}


5)
get_ext5($file_name)

{
    return strrev(substr(strrev($file_name), 0, strpos(strrev($file_name), '.')));
}

 

26.如何修改SESSION的生存时间

答:其实 Session 还提供了一个函数 session_set_cookie_params(); 来设置 Session 的生存期的,该函数必须在 session_start() 函数调用以前调用:

<?php

// 保存一天

$lifeTime = 24 * 3600;

session_set_cookie_params($lifeTime);

session_start();

$_SESSION["admin"] = true;

?>

 

27. 请写一个函数,实现如下功能: 字符串“open_door” 转换成 “OpenDoor”、”make_by_id” 转换成 ”MakeById”。

$arr1=explode('_',$str);

 

$str = implode(' ',$arr1);
return ucwords($str);
 

28.表中有A B C三列,SQL语句实现:当A列大于B列时选择A列不然选择B列,当B列大于C列时选择B列不然选择C列。

答:select case when A>B then A else B end,
       case when B>C then B else C end
From test

 

 

30.请简述项目中优化sql语句执行效率的方法,从哪些方面,sql语句性能如何分析?

答:(1)选择最有效率的表名顺序

2WHERE子句中的链接顺序

3SELECT子句中避免使用‘*’

4)用Where子句替换HAVING子句


5)经过内部函数提升SQL效率

6)避免在索引列上使用计算。

7)提升GROUP BY 语句的效率, 能够经过将不须要的记录在GROUP BY 以前过滤掉。

 

 

31.如何经过javascript判断一个窗口是否已经被屏蔽

答:获取open()的返回值,若是是null,就是屏蔽了

 

 

32.对于大流量的网站,您采用什么样的方法来解决访问量问题

答:首先,确认服务器硬件是否足够支持当前的流量

其次,优化数据库访问。

第三,禁止外部的盗链。

第四,控制大文件的下载。

第五,使用不一样主机分流主要流量

第六,使用流量分析统计软件

 

33.写一个函数,尽量高效的,从一个标准 url 里取出文件的扩展名 例如: http://www.sina.com.cn/abc/de/fg.php?id=1 须要取出 php 或 .php

$url = 'http://www.sina.com.cn/abc/de/fg.php?id=1';
$arr = parse_url($url);
$path = $arr['path'];
$pathinfo = pathinfo($path);
$ext = $path['extension'];
 
34.输出一个文件先对于另外一个文件的相对路径
$a = '/a/b/c/d/e.php';
$b = '/a/b/12/34/c.php';
function getRelativePath($path1, $path2) {
	$arr_path1 = explode('/', $path1);
	$arr_path2 = explode('/', $path2);
	foreach($arr_path1 as $key => $val) {
		if ($arr_path1[$key] == $arr_path2[$key]) {
			unset($arr_path1[$key], $arr_path2[$key]);
		}
	}
	return str_repeat('../', count($arr_path1) - 1) . implode('/', $arr_path2);
}
$reltive_path = getRelativePath($a, $b);
echo $reltive_path;

 

35. 简单说明PHP的垃圾收集机制是怎样的?
对变量有个引用计数,计数到0时变量被销毁。

 

36.使对象能够像数组同样进行foreach循环,要求属性必须是私有

php5里面已经有了iterator接口,只要实现该接口,便可以实现对象私有属性被foreach遍历

 
class Sample implements iterator{

private $var = array(1,2,3,4,5);

public function __construct(){}

public function rewind(){ reset($this->var);}

public function current(){return current($this->var);}

public function key(){return key($this->var);}

public function next(){return next($this->var);}

public function valid(){return ($this->current()!==false);}

}

$s = new Sample();

foreach($s as $k=>$v){ echo $k.'='.$v.'<br/>';}

37、__destruct /unset 
__destruct() 析构函数,是在垃圾对象被回收时执行。 
unset 销毁的是指向对象的变量,而不是这个对象。

 

3八、 Session 与 GC 
因为PHP的工做机制,它并无一个daemon线程来按期的扫描Session信息并判断其是否失效,当一个有效的请求发生时,PHP 会根据全局变量 session.gc_probability和session.gc_divisor的值,来决定是否启用一个GC, 在默认状况下,session.gc_probability=1, session.gc_divisor =100也就是说有1%的可能性启动GC(也就是说100个请求中只有一个gc会伴随100个中的某个请求而启动). 
GC的工做就是扫描全部的Session信息,用当前时间减去session最后修改的时间,同session.gc_maxlifetime参数进行比较,若是生存时间超过gc_maxlifetime(默认24分钟),就将该session删除。 
可是,若是你Web服务器有多个站点,多个站点时,GC处理session可能会出现意想不到的结果,缘由就是:GC在工做时,并不会区分不一样站点的session. 

那么这个时候怎么解决呢? 
1. 修改session.save_path,或使用session_save_path()让每一个站点的session保存到一个专用目录, 
2. 提供GC的启动率,天然,GC的启动率提升,系统的性能也会相应减低,不推荐。 
3. 在代码中判断当前session的生存时间,利用session_destroy()删除.

 

39. 012/4 输出多少?
输出2.5;  012为8进制数据,转为10进制对应为 10
 
40.实现php排序算法及指出复杂度:
 <?php
// 冒泡排序
function BubbleSort($arr) {
    // 得到数组总长度
    $num = count($arr);
    // 正向遍历数组
    for ($i = 1; $i < $num; $i++) {
        // 反向遍历
        for ($j = $num - 1; $j >= $i ; $j--) {
            // 相邻两个数比较
            if ($arr[$j] < $arr[$j-1]) {
                // 暂存较小的数
                $iTemp = $arr[$j-1];
                // 把较大的放前面
                $arr[$j-1] = $arr[$j];
                // 较小的放后面
                $arr[$j] = $iTemp;
            }
        }
    }
    return $arr;
}

// 交换法排序
function ExchangeSort($arr){
    $num = count($arr);
    // 遍历数组
    for ($i = 0;$i < $num - 1; $i++) {
        // 得到当前索引的下一个索引
        for ($j = $i + 1; $j < $num; $j++) {
            // 比较相邻两个的值大小
            if ($arr[$j] < $arr[$i]) {
                // 暂存较小的数
                $iTemp = $arr[$i];
                // 把较大的放前面
                $arr[$i] = $arr[$j];
                // 较小的放后面
                $arr[$j] = $iTemp;
            }
        }
    }
    return $arr;
}

// 选择法排序
function SelectSort($arr) {
    // 得到数组总长度
    $num = count($arr);
    // 遍历数组
    for ($i = 0;$i < $num-1; $i++) {
        // 暂存当前值
        $iTemp = $arr[$i];
        // 暂存当前位置
        $iPos = $i;
        // 遍历当前位置之后的数据
        for ($j = $i + 1;$j < $num; $j++){
            // 若是有小于当前值的
            if ($arr[$j] < $iTemp) {
                // 暂存最小值
                $iTemp = $arr[$j];
                // 暂存位置
                $iPos = $j;
            }
        }
        // 把当前值放到算好的位置
        $arr[$iPos] = $arr[$i];
        // 把当前值换成算好的值
        $arr[$i] = $iTemp;
    }
    return $arr;
}

// 插入法排序
function InsertSort($arr){
    $num = count($arr);
    // 遍历数组
    for ($i = 1;$i < $num; $i++) {
        // 得到当前值
        $iTemp = $arr[$i];
        // 得到当前值的前一个位置
        $iPos = $i - 1;
        // 若是当前值小于前一个值切未到数组开始位置
        while (($iPos >= 0) && ($iTemp < $arr[$iPos])) {
            // 把前一个的值日后放一位
            $arr[$iPos + 1] = $arr[$iPos];
            // 位置递减
            $iPos--;
        }
        $arr[$iPos+1] = $iTemp;
    }
    return $arr;
}

// 快速排序
function QuickSort($arr){
    $num = count($arr);
    $l = $r = 0;
    // 从索引的第二个开始遍历数组
    for ($i = 1;$i < $num; $i++) {
        // 若是值小于索引1
        if ($arr[$i] < $arr[0]) {
            // 装入左索引数组(小于索引1的数据)
            $left[] = $arr[$i];
            $l++;
        } else {
            // 不然装入右索引中(大于索引1的数据)
            $right[] = $arr[$i];
            $r++; //
        }       
    }
    // 若是左索引有值 则对左索引排序
    if($l > 1) {
        $left = QuickSort($left);
    }
    // 排序后的数组
    $new_arr = $left;
    // 将当前数组第一个放到最后
    $new_arr[] = $arr[0];
    // 若是又索引有值 则对右索引排序
    if ($r > 1) {
        $right = QuickSort($right);
    }
    // 根据右索引的长度再次增长数据
    for($i = 0;$i < $r; $i++) {
        $new_arr[] = $right[$i];
    }
    return $new_arr;
}
?>

 

41.下面的程序错在哪里?
class Box {
	protected $num = 0;
	public function __construct() {
		$this->num = 2;
	}
	
	public static function getNum() {
		return $this->num;
	}
}

$obj = new Box();
echo Box::getNum();

由于方法getNum被申明为静态的,故他的方法体里只能有静态的属性(用self:: 调用也不能够,由于$num是实例属性,若是没有
建立实例,则不能调用)

应该把发放声明中的static去掉

 

4二、utf8 和 UTF-8 有什么区别

“UTF-8”是标准写法,在Windows下边英文不区分大小写,因此也能够写成“utf-8”。“UTF-8”也能够把中间的“-”省略,写成“UTF8”。通常程序都能识别,但也有例外(以下文),为了严格一点,最好用标准的大写“UTF-8”。

在MySQL数据库中只能使用“utf8”

  在MySQL的命令模式中只能使用“utf8”,不能使用“utf-8”,也就是说在PHP程序中只能使用“set names utf8(不加小横杠)”,若是你加了“-”此行命令将不会生效,可是在PHP中header时却要加上“-”,由于IE不认识没杠的“utf8”,缘由 见下文。

在IE浏览器中只能使用“utf-8”

  IE中若是使用了“utf8”,页面可能会 空白 或 显示为乱码。

  可是在其它浏览器倒是正常的,缘由是由于:其它浏览器默认使用的是UTF-8的编码,若是没法识别页面的编码就会用默认的UTF-8来解码,但 是IE的默认编码是GB2312,因此默认的话就。。。。。(其它浏览器指“FireFox”、“Chrome”、“Opera”)


总结  

  【只有在MySQL中可使用“utf-8”的别名“utf8”,可是在其余地方一概使用大写“UTF-8”。】

  具体为:

    在命令“mysql_query(set names utf8)”外一概用大写“UTF-8”。

相关文章
相关标签/搜索