一、选择题 3. 有如下代码:
<?php
$x="display";
${$x.'_result'}();
?>
以上代码将会调用display_result()______
A B C D
C
[解析] 在PHP中,如果一个函数的名字不是确定的,那么可以把函数名存放到一个变量中,然后通过如下两种方法调用: 1)直接通过“$变量名()”进行调用。 2)通过内置函数来进行调用,即 ①mixed call_user_func(callback $function[,mixed $parameter[,mixed$...]]) ②mixed call_user_func_array(callback $function,array $param_arr) 示例代码如下: <?php function hello($name) { echo"hello $name\n"; } $f="hello"; $f("world"); //输出hello world call_user_func('hello',"world"); //输出hello world ?> 对于本题而言,通过$x.'_result'拼接出的字符串为display_result,因此,${$x.'_result'}()也就等价于$display_result(),显然变量名display_result是不存在的,因此编译无法通过,一种可行写法为$y=$x.'_result';$y();。 所以,本题的答案为C。
7. 设有一个数据库mydb中有一个表tb1,表中有6个字段,主键为ID,有10条记录,ID为0~9,以下代码输出结果是______
<?php
$link=mysq1_connect("localhost","mysq1_user","mysq1_password")
ordie("Could not connect:".mysq1_error());
$result=mysq1_query("SELECT id,name,age FROM mydb、tb1 where id<5");
ordie("Could not query:.mysq1_error());
echo mysq1_num_fields($result);
mysq1_close($link);
?>
A B C D
D
[解析] mysql_num_fields()返回结果集中字段的数目,该语句主要查询了id、name和age三个字段。选项D正确。 所以,本题的答案为D。
二、填空题 1. 运行时(run-time)包含一个PHP脚本使用______,而编译时(compile-time)包含一个PHP脚本使用______。
include,require。
[解析] require(或requier_once())和include()(或include_once())都可以用来包含PHP文件,它们的唯一区别是,如果包含的文件不存在,那么require(或require_once())将产生一个致命错误,同时终止脚本的执行;而include(或include_once())只会产生一个警告,不终止后续脚本的执行。二者在运行和编译引用文件时没有区别。
2. 函数______能读取文本文件中的一行。读取二进制文件或者其他文件时,应当使用______函数。
fgets(),fread()。
[解析] fgets()函数主要用于读取文本文件中的一行,而fread()函数主要用于读取二进制文件。fseek()函数主要用于在打开的文件中定位,fputs()函数用于写入文件。
3. ______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
debug_backtrace。
[解析] debug_backtrace()的作用是,返回在特定位置调用过的函数名组成的数组,经常被用于调试中。
4. 需要设置一个有效期为31天的Memcache值,请补充下面的代码:
<?php
$memcache_obj=new Memcache();
$memcache_obj->connect('memcache_host,11211');
$memcache_obj->set('varKey','varValue',0, );
?>
time()+31*24*3600或31*24*3600。
[解析] 首先初始化Memcache对象,然后进行Memcache连接,最后用set方法设置过期时间。memcache::set语法为memcache::set("键","值","是否压缩","设置过期时间,0为永久不过期"),其中时间值可以是一个时间戳,也可以是秒数。所以设置一个有效期为31天的Memcache值方法格式为memcache::set("key","value",0,time()+31*24*3600)。
5. 在PHP中,heredoc是一种特殊的字符串,它的结束标志必须______。
顶格写,且以分号“;”结束。
[解析] heredoc的语法是用“<<<”加上自己定义成对的标签,在标签范围内的文字视为一个字串。结束表示符必须独占一行,且必须顶格写,最后以“;”分号结尾。示例代码如下: <?php $str=<<<ED hello world. ED; echo $str; ?> 运行结果为 hello world.
四、编程题 1. 据说著名犹太历史学家约瑟夫(Josephus)有过以下的故事:在罗马人占领乔塔帕特后,39个犹太人与约瑟夫及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3个人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
然而约瑟夫和他的朋友并不想遵从,约瑟夫要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
约瑟夫问题可用代数分析来求解,假设现在您与m个朋友不幸参与了这个游戏,您要如何保护您与您的朋友?
实际上只要画两个圆圈就可以让自己与朋友免于死亡游戏,这两个圆圈中内圈是排列顺序,而外圈是自杀顺序,如下图所示。
使用程序来求解时,只要将阵列当作环状来处理,在阵列中由计数1开始,每三个数得到一个计数,直到计数到41为止;然后将阵列由索引1开始列出,就可以得知每个位置的自杀顺序,这就是约瑟夫排列。41个人报数的约瑟夫排列如下(第一个开始对应每个人的站位):
14 36 1 38 15 2 24 30 3 16 34 4 25 17 5 40 31 6 18 26 7 37 19 8 35 27 9 20 32 10 41 21 11 28 39 12 22 33 13 29 23
由上可知,最后一个自杀的是在第31个位置的人,而倒数第二个自杀的要排在第16个位置,之前的人都死光了,所以他们也就不知道约瑟夫与他的朋友并没有遵守游戏规则。
实现代码如下:
<?php
header("content-type:text/html;charset=utf-8");
define("N",41);
//参与总人数
define("M",3);
//每到3自杀一人
$man=array(0);
$count=1;
$i=0;
$pos=-1;
$alive=2;
//想救的人数
while($count<=N){
do{
$pos=($pos+1)%N;
//环状处理
if(@$man[$pos]==0)
$i++;
if($i==M){
$i=0;
break;
}
}while(1);
$man[$pos]=$count;
$count++;
}
//截取出对应最大键值对应的键名
arsort($man);
$arr=array_slice($man,0,$alive,true);
echo"约琴夫排列:";
for($i=0;$i<N;$i++){
echo"".$man[$i];
}
echo"<br>L表示要救的".$alive."个人要放的位置:";
for($i=0;$i<N;$i++){
if(isset($arr[$i])&&$man[$i]==$arr[$i])
echo"L";
else
echo"D";
if(($i+1)%5==0) echo" ";
}
?>
程序的运行结果为
约琴夫排列:14 36 1 38 15 2 24 30 3 16 34 4 25 17 5 40 31 6 18 26 7 37 19 8 35 27 9 20 32 10 41 21 11 28 39 12 22 33 13 29 23
L表示要救的2个人要放的位置:DDDDD DDDDD DDDDD LDDDD DDDDD DDDDD LDDDD DDDDDD
2. 一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如,6=1+2+3。编程找出1000以内的所有完数。
外层循环998次,每次循环得到的$i传入下个循环内,内部循环求解出符合$i整除$k等于0的数,如果能够整除,那么说明$k是$i的一个因子,则用$sum累加,直到$sum+1等于$i条件成立,说明$i是一个“完数”。需要注意的是,因为$sum求解出的因子是不包括1的,所以还需要额外地加1到$sum中,并且$i的一个因子不会大于$i/2,所以内部循环判断是否继续循环的条件为$i/2。 实现代码如下: <?php for($i=2;$i<1000;$i++){ $sum=0; for($k=2;$k<=$i/2;$k++){ if($i%$k==0){ $sum+=$k; } } if($sum+1==$i){ echo $i." "; } } ?> 程序的运行结果为 6 28 496
3. 实现一个队列的数据结构,使其具有入队列、出队列、查看队列首尾元素、查看队列大小等功能。
队列的实现也有两种方法,分别为采用数组来实现和采用链表来实现。下面分别详细介绍这两种方法。
下图给出了一种最简单的实现方式,用front来记录队列首元素的位置,用rear来记录队列尾元素往后一个位置。入队列的时候只需要将待入队列的元素放到数组下标为rear的位置,同时rear++,出队列的时候只需要执行行front++即可。
实现代码如下:
<?php
header("content-type:text/html;charset=utf-8");
class queue{
private $queueList;
private $size;
public function__construct(){
$this->queueList=array();
$this->size=0;
}
//入队操作
public function enQueue($data){
$this->queueList[$this->size++]=$data;
return $this;
}
//出队操作
public function outQueue(){
if(!$this->isEmpty()){
--$this->size;
$front=array_splice($this->queueList,0,1);
return $front[0];
}
return false;
}
//获取队列
public function getQueue(){
return $this->queueList;
}
//获取队头元素
public function getFront(){
if(!$this->isEmpty()){
return $this->queueList[0];
}
return false;
}
//获取队尾元素
public function getRear(){
if(!$this->isEmpty()){
$len=count($this->queueList);
return $this->queueList[$len-1];
}
return false;
}
//获取队列的长度
public function getSize(){
return $this->size;
}
//检测队列是否为空
public function isEmpty(){
return 0===$this->size;
}
}
$queue=new queue();
$queue->enQueue(1);
$queue->enQueue(2);
echo"队列头元素为:".$queue->getFront();
echo"<br>队列尾元素为:".$queue->getRear();
echo"<br>队列大小为:".$queue->getSize();
?>
程序的运行结果为
队列头元素为:1
队列尾元素为:2
队列大小为:2
4. IP是否可以伪造?PHP中如何拿到真实IP?
IP地址是可以伪造的,客户端可以伪造IP地址或使用代理IP导致IP地址不是用户的真实IP地址。 在$_SERVER函数中,参数REMOTE_ADDR代表客户端的IP地址,HTTP_X_FORWARDED_FOR是代理服务器的IP地址,存放真实的IP和各级代理IP。实现代码如下: <?php function getIP(){ $unknown='unknown'; if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'],$unknown)){ $IP=$_SERVER['HTTP_X_FORWARDED_FOR']; }elseif(isset($_SERVER['REMOTE_ADDR'])&&$_SERVER['REMOTE_ADDR'] &&strcasecmp($_SERVER['REMOTE_ADDR'],$unknown)){ $IP=$_SERVER['REMOTE_ADDR']; } if(false!==strpos($IP,','))$IP=reset(explode(',',$IP)); return $IP; } ?>