澳门新葡萄京官网注册PHP中static关键字原理的学习研究分析

$a =
abcababa;$count=strpos($a,ab);$str=substr_replace($a,,$count,2);输出结果:cababa代码虽短,但也算是一个小算法!

看PHP手册的时候发现了下面这样一段代码:
复制代码 代码如下:
function Test()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
Test();
}
$count–;
}
?>

图书目录输入部分: ? if(!$UploadAction): ? ?
//本程序是为输入书名,作者、出版社资料而设。
//编者:孔秀祥。日期:2001/3/24 /* session_start(); if
(!isset($auth_passed)) { echo 本功能只有授权用户才能使用。; return -1;
} if(isset($u_name)) { session_name($u_name); //echo centerfont
color=’red’.session_name().:本程序将竭诚为您服务。/font/center/n;
//echo hr; } */ ? HTMLHEAD TITLE图书目录输入 /TITLE /HEAD BODYTABLE
align=CENTER FORM ENCTYPE= multipart/form-data NAME = SubmitForm ACTION=
? $PHP_SELF ? METHOD = POST INPUT TYPE= hidden NAME = MAX_FILE_SIZE
VALUE =20000000 INPUT TYPE= hidden NAME = UploadAction VALUE = 1
!–TRTD文件名TDINPUT NAME = UploadFile TYPE = file VALUE= SIZE = 30/TR–
TRTD 著作名TDINPUT NAME = b_name TYPE = text VALUE= SIZE = 30
maxlength=100/TD/TR TRTD 作者TD姓INPUT NAME = a_first1 TYPE = text
VALUE= SIZE = 6 maxlength=20 名INPUT NAME = a_last1 TYPE = text VALUE=
SIZE = 6 maxlength=20/TD/TR TRTD 作者TD姓INPUT NAME = a_first2 TYPE =
text VALUE= SIZE = 6 maxlength=20 名INPUT NAME = a_last2 TYPE = text
VALUE= SIZE = 6 maxlength=20/TD/TR TRTD 作者TD姓INPUT NAME = a_first3
TYPE = text VALUE= SIZE = 6 maxlength=20 名INPUT NAME = a_last3 TYPE =
text VALUE= SIZE = 6 maxlength=20/TD/TR TD编著方式/TD TD SELECT size=1
name=author_type TYPE = int default=11 OPTION selected value=11著
/OPTION OPTION selected value=12编著 /OPTION OPTION value=13主编/OPTION
OPTION value=14副主编/OPTION OPTION value=15 参编/OPTION OPTION value=16
注 /OPTION OPTION value=17 编 /OPTION OPTION value=18 选 /OPTION OPTION
value=19 评 /OPTION OPTION value=20其他/OPTION /SELECT 定价INPUT NAME =
b_price_a TYPE = text VALUE= SIZE = 3.INPUT NAME = b_price_b TYPE =
text VALUE= SIZE = 2元 /TR TRTD 出版社TDINPUT NAME = p_name TYPE = text
VALUE= SIZE = 30 maxlength=100/TD/TR TRTD出版日期TDINPUT NAME = p_year
TYPE = text VALUE= SIZE = 4年 INPUT NAME = p_month TYPE = text VALUE=
SIZE = 2月TRTDISBNTDINPUT NAME = isbn TYPE = text VALUE= SIZE = 25 TRTD
rowspan=5有关书的说明/TD !–/TRTR– TD rowspan=5TEXTAREA wrap=on rows=5
cols=30 NAME = b_comment SIZE = 255 /TEXTAREA/TD /TR /TABLE TABLE TRTD
INPUT NAME = submit VALUE = 提交 TYPE = submit TDINPUT NAME = reset
VALUE = 重置 TYPE = reset /TD/TR /FORM/CENTER/TABLE/BODY /HTML ? else:
session_start(); require config.php3;
$b_price=trim($b_price_a)./..trim($b_price_b);
if(strlen($p_month)==1) $p_month=0.trim($p_month); if($p_month==)
$p_month=01; $date_pub=trim($p_year).-.trim($p_month).-01;
$UploadAction=0; $repeat=0;//是不是重复了。 $TimeLimit=0;
//设置超时限制时间缺省时间为 30秒设置为0时为不限时
set_time_limit($TimeLimit);
@MYSQL_CONNECT($hostname,$dbusername,$dbpassword) OR
DIE(不能连接数据库!); @mysql_select_db($dbname) or
die(不能选择数据库!); //$q=select books.books_id,
books.books_name,author.first_name,author.last_name,publisher.publisher_name
from books,author,books_author,publisher where
books.books_name=/$b_name/ and
books.publisher_id=publisher.publisher_id and
books.books_id=books_author.books_id and
books_author.author_id=author.author_id; $b_name=trim($b_name);
$sele=select books.books_id,
books.books_name,author.first_name,author.last_name,publisher.publisher_name,books.ISBN,books.price,books.date_pub,books.pages;
$fro= from books,author,books_author,publisher ; if(trim($isbn)!=)
$whe=where books.ISBN=/$isbn/ ; elseif(trim($a_first1)!= &&
trim($a_last1)!= && trim($p_name)!=) $whe= where
books.books_name=/$b_name/ and
books.publisher_id=publisher.publisher_id and
books.books_id=books_author.books_id and
books_author.author_id=author.author_id; else{
$msg=书名为必填,其他如果ISBN为空,则作者的姓、名,出版社为必填。BR请检查是否符合要求。;
xueroom_error_exit($msg,$PHP_SELF); } $q=$sele$fro$whe; /*
books.books_id,books.books_name, author.first_name,
author.last_name, publisher.publisher_name books.ISBN, books.price,
books.date_pub, books.pages */ $r = @mysql_query($q);
//$count=@mysql_fetch_row($r); //echo 书名.$count[1].BR; if(!$r){
echo 查询无效 BR; exit; } if(mysql_num_rows($r)){ if(trim($isbn)!=){
echo 数据重复。BR; exit; } else
while($count=mysql_fetch_array($r)){/* echo while。BR; echo
trim($a_first1); echo trim($count[2]); echo
trim($a_first1)==trim($count[2]); echo BR; echo
trim($a_last1)==trim($count[3]); echo BR; echo
trim($p_name)==trim($count[4]); echo BR; */ if(
trim($a_first1)==trim($count[2]) &&
trim($a_last1)==trim($count[3]) &&
trim($p_name)==trim($count[4])){ $data_exist+=1;
$books_id=$count[0];
$books_name=$count[1];$first_name=$count[2];
$last_name=$count[3]; $repeat=1; echo 本书已经在数据库中。BR;echo
font color=’red’书名:/font.$books_name; echo BRfont
color=’blue’作者:/font.$first_name.$last_name; echo BRfont
color=’red’国标标准书号:/font.$count[5]; echo BRfont
color=’blue’书价:/font.$count[6].元; echo BRfont
color=’red’出版日期:/font.substr($count[7],0,4).年.substr($count[7],5,2).月;
if($count[8]) echo font color=’blue’页码:/font.$count[8].页;
echoBRA HREF = $PHP_SELF返回 /A; //$repeat=0; exit; //break; }
}//while($count=mysql_fetch_array($r)){}//if(mysql_num_rows($r){
//if(!$repeat){ if($p_name!=){ $p_name=trim($p_name);
$address=trim($address); $zipcode=trim($zipcode);
$telephone=trim($telephone); $telefax=trim($telefax);
$email=trim($email); $s_publisher=select publisher_id from publisher
where publisher_name=/$p_name/; $results1 =
@mysql_query($s_publisher); $count1=mysql_fetch_array($results1);
if(mysql_num_rows($results1)1){ $q_publisher=INSERT INTO publisher
(publisher_name, address, zipcode, telephone, telefax, email) VALUES
(/$p_name/, /$address/, /$zipcode/, /$telephone/, /$telefax/,
/$email/); $result2 = @mysql_query($q_publisher); if($result2){
$publisher_id= mysql_insert_id(); } } else $publisher_id=
$count1[0]; } if($b_name==){ echo书名不能为空。; exit; } else{
$b_name=trim($b_name); $publisher_id=trim($publisher_id);
//$date_pub=trim($date_pub); $type=trim($type); $pages=trim($pages);
//$b_price=trim(); $isbn=trim($isbn); $s_books=select books_id from
books where books_name=/$b_name/ ; $results3 =
@mysql_query($s_books); $count3=mysql_fetch_array($results3);
if(mysql_num_rows($results3)1){ $q_books=INSERT INTO books
(books_name, publisher_id, date_pub, type, pages, price,ISBN) VALUES
(/$b_name/, /$publisher_id/, /$date_pub/, /$type/, /$pages/,
/$b_price/,/$isbn/);$result3 = @mysql_query($q_books); if($result3){
$books_id= mysql_insert_id(); } } else $books_id=$count3[0]; }
if(($a_first1==)||($a_last1==)){ echo第一作者的姓名不能为空。; //exit;
} else{ $a_first1=trim($a_first1); $a_last1=trim($a_last1);
$address=trim($address); $zipcode=trim($zipcode);
$telephone=trim($telephone); $email=trim($email); $s_author=select
author_id from author where first_name=/$a_first1/ and
last_name=/$a_last1/; $results = @mysql_query($s_author);
$count2=mysql_fetch_array($results); if(mysql_num_rows($results)1){
$q_author=INSERT INTO author (first_name, last_name, address,
zipcode, telephone, email) VALUES (/$a_first1/, /$a_last1/,
/$address/,/$zipcode/, /$telephone/, /$email/); $result1 =
@mysql_query($q_author); if($result1){ $author_id=
mysql_insert_id(); } } else $author_id =$count2[0];
if($books_id!=||$author_id!=){ $s_ba=select id from books_author
where books_id=/$books_id/ and author_id=/$author_id/; $resulta =
@mysql_query($s_ba); //$counta=mysql_fetch_array($resulta);
if(mysql_num_rows($resulta)1){ $q_books_author=INSERT INTO
books_author (books_id, author_id, author_type) VALUES
(/$books_id/, /$author_id/, /$author_type/); $author_id=; $resulta =
@mysql_query($q_books_author); } } }
if(($a_first2!=)||($a_last2!=)){ $a_first2=trim($a_first2);
$a_last2=trim($a_last2); $s_author2=select author_id from author
where first_name=/$a_first2/ and last_name=/$a_last2/; $results5 =
@mysql_query($s_author2); $count5=mysql_fetch_array($results5);
if(mysql_num_rows($results5)1){ $q_author2=INSERT INTO author
(first_name, last_name, address, zipcode, telephone, email) VALUES
(/$a_first2/, /$a_last2/, /$address/,/$zipcode/, /$telephone/,
/$email/); $result2 = @mysql_query($q_author2); if($result2){
$author_id= mysql_insert_id(); } } else $author_id =$count5[0];
if($books_id!=||$author_id!=){ $s_ba=select id from books_author
where books_id=/$books_id/ and author_id=/$author_id/; $resulta =
@mysql_query($s_ba); //$counta=mysql_fetch_array($resulta);
if(mysql_num_rows($resulta)1){ $q_books_author=INSERT INTO
books_author (books_id, author_id, author_type) VALUES
(/$books_id/, /$author_id/, /$author_type/); $author_id=; $resulta =
@mysql_query($q_books_author); } } }
if(($a_first3!=)||($a_last3!=)){ $a_first3=trim($a_first3);
$a_last3=trim($a_last3); $s_author3=select author_id from author
where first_name=/$a_first3/ and last_name=/$a_last3/; $results6 =
@mysql_query($s_author3); $count6=mysql_fetch_array($results6);
if(mysql_num_rows($results6)1){ $q_author3=INSERT INTO author
(first_name, last_name, address, zipcode, telephone, email) VALUES
(/$a_first2/, /$a_last2/, /$address/,/$zipcode/, /$telephone/,
/$email/); $result3 = @mysql_query($q_author3); if($result3){
$author_id= mysql_insert_id(); } } else $author_id =$count6[0];
if($books_id!=||$author_id!=){ $s_ba=select id from books_author
where books_id=/$books_id/ and author_id=/$author_id/; $resulta =
@mysql_query($s_ba); //$counta=mysql_fetch_array($resulta);
if(mysql_num_rows($resulta)1){ $q_books_author=INSERT INTO
books_author (books_id, author_id, author_type) VALUES
(/$books_id/, /$author_id/, /$author_type/); $author_id=; $resulta =
@mysql_query($q_books_author); } } } echoBRA HREF = $PHP_SELF返回
/A; echo/BODY/HTML; ? ? endif; ?

执行结果如下:
这是一个递归的函数,声明的静态变量count记录次数,输出1~10。
我在看的时候有个疑惑,递归调用的时候 static $count = 0;
语句会重复执行,这为什么不会导致count变量被重复赋值呢?带着这个疑问和同事研究了一下,测试用代码如下:
复制代码 代码如下:
echo ‘start
‘;
static $a = 10;
echo “$a
“;
unset($GLOBALS[‘a’]);
echo “$a
“;
static $a = 20;
echo “$a
“;
$GLOBALS[‘a’] = 10;
echo “$a
“;
static $a = 30;
echo “$a
“;
unset($GLOBALS[‘a’]);
echo “$a
“;
static $a;
echo “$a
“;
static $a = 40;
echo “$a
“;
$a = 100;
echo “$a
“;
static $a = 50;
echo “$a
“;
static $a = 4;
echo “$a
“;
echo ‘end
‘;
exit;
?>

执行结果如下:
start

  1. Notice:
    Undefined variable: a 
  2. 10 
  3. 10 
  4. Notice:
    Undefined variable: a 
  5. 10 
  6. 10 
  7. 100 
  8. 100 
  9. 100 
  10. end

(结果中关于文件位置的部分已删去。也可以去掉echo语句使用zend的debug功能查看,这样结果更清晰)

代码第5行第一次输出$a的值为4,由此推测PHP在页面初始化的时候分配静态变量的内存,此时使用了同一个变量的最后一次声明的值(这个可以把4改为其他数测试)。代码第7行调用unset函数销毁变量$a,再次输出$a的值时看到未定义变量的提示,说明变量已经被销毁。

第10行再次输出时,输出结果仍是4而不是20,有两种可能,一个是php再次初始化了$a的值,另一种是php使用了$a被销毁前的值,这个问题在第20行输出的时候解决。第16行$a销毁的时候值为10,第19行声明后输出仍为10。

第11行将$a的值修改为10,在14行再次声明$a,17行输出认为10。推测为重复声明时php还是使用静态变量内存中的值,而不再次赋值。

至此,手册中发现的问题,大致上已经解决了,即递归调用中的声明没有改变$count的值,所以递归在$count=10时成功停止。

可能有理解不正确的地方,欢迎拍砖。

发表评论

电子邮件地址不会被公开。 必填项已用*标注