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」。

相關文章
相關標籤/搜索