解析:
问题的表述很简洁,无需过多解释,假设函数原型为array_remove($v , $array)。需要注意的几点有:
<1> 对于参数的检查.如果$array不是数组的话,返回错误或者抛出异常。
<2> 如何比较数组的值与$v相等?是== 还是 ===?这里存在分歧。为了简单起见,我们假设是==比较。
现在我们加一些限制条件,对于以下一些限制条件,应该如何解决:
a.如果不使用系统函数。如何解决?
b.参数传递问题:传递引用和传值对于函数的编写有何影响?分别实现之。
c.可以使用系统函数的情况下,如何解决。
我们先看条件一:如果不使用系统函数。如何解决?直接遍历吧,遇到value等于$v的项目,就删除它(或者遇到不等于value的元素,就记录下来)。因而有两种形式:
<?php /* * 方式1,直接传递引用,修改原数组 */ function array_remove($v,&$array){ if(!is_array($array)){ throw new Exception("input param is not a legel ,should be array\n"); } foreach($array as $key=>$value){ if($value == $v){ unset($array[$key]); } } } /* * 方式2.传递值。返回修改后的新数组。 */ function array_remove_return($v,$array){ if(!is_array($array)){ throw new Exception("input param is not a legel ,should be array\n"); } $result = array(); foreach($array as $key=>$value){ if($value != $v){ $result[$key] = $value; } } return $result; } $test = array(1,2,3,4,5); $test2 = array(1,2,3,4,5); array_remove(3,$test); print_r($test); $res = array_remove_return(3,$test2); print_r($res);
限制条件c:如果可以用系统函数的话。有哪些解法?
这个解法也有很多。最基本的,我们可以用array_search找出value等于$v的索引,然后删除相应的元素。代码如下:
function array_remove_with_inside($v,&$array){ if(!is_array($array)){ throw new Exception("input param is not a legel ,should be array\n"); } $key = array_search($v,$array); if($key !== false){ unset($array[$key]); } }代码中需要注意的地方是第六行: if($key !== false) 。这里的比较是 !==而不是 != 。为什么呢?这是因为:
array_search($v,$array);的结果可能是0(数组的第一个元素)。而在php中0==false但是0!== false.这是一个需要注意的地方。与这个情况类似的是遍历目录时候。 while(($file = readdir($handler))!==false)这也是防止出现名字为0的目录或文件而产生错误。当然也可以使用array_walk删除相应的元素。代码稍后补上。
类似的题目还有:reverse($string)的编写等,对于库函数的编写是一项基本能力,主要的考点是:效率,参数检测,错误处理等大多数需要考虑十分仔细和周全。
<?php
$m = $_GET['m'];
$user = $_GET['user'];
$pass = $_GET['pass'];
include($m.”do.php”);
$sql = ”select count(*) as b from user where username=’”.$user.”‘and password=’”.$pass.”‘;
$r = mysql_query($sql);
list($count) = @mysql_fetch_array($r);
if($count>1){
……登陆成功操作
}
?>
解析:
<1>用户名和密码都是通过get方式明文传递的。这是一个很严重的问题。虽然post方式也并不是安全的,但是对于这种表单提交,还是post方式最好。
<2>没有过滤用户的输入。存在者严重的sql注入隐患。应该htmlspecialchars ,trim,strip_tags处理用户输入。有一个原则叫:永远不要相信用户的输入。这里就是这个道理。
<3>sql查询部分。貌似数据库中保存的明文?至少应该做md5加密,然后比较md5加密的结果。
<4>include($m.”do.php”); 把用户的输入作为参数,而且不做处理的话,这里很容易出现“文件不存在”的异常
当然还有不是安全隐患的错误地方:if($count>1) 题目错误,会有两个以上同用户名同密码的用户吗?if($count >= 1)(好吧假设有,这里起码应该有=1)
例如:
函数原型为 getRelativeDir($dir1,$dir2)求出$dir1相对于$dir2的相对路径。
解析:
最简单的想法。记录两个目录相同的部分并计数。如果计算出记录dir2跳出到相同目录下需要的次数。并添加 “ ../”。最后可以求出目录一相对于目录二的相对路径。
代码如下:
function getRelativePath($dest_dir,$relative_dir){ $path_dest = explode('/',dirname($dest_dir)); $path_relative = explode('/',dirname($relative_dir)); $aLen = count($path_dest); $bLen = count($path_relative); $minLen = min($aLen,$bLen); $count = 0; for($i = 0; $i < $minLen; $i++){ if( $path_dest[$i] == $path_relative[$i] ){ $count++; } } $path = ''; $res_count = $bLen - $count - 1; for($i = 0;$i < $res_count;$i++){ $path.= "../"; } for($i = $res_count;$i < $aLen;$i++){ $path.= $path_dest[$i]."/"; } $path.= basename($dest_dir); return $path; } $a = '/a/b/c/f/d/e.php'; $b = '/a/b/f/g/k/h/j.php'; echo getRelativePath($a,$b);
解析:基本考点:file_get_contents 或者curl获取网络内容 .正则表达式匹配。file_put_contents或者文件操作函数。并无太大难点。
作为测试,(谷歌被墙了),抓取baidu的相关搜索结果。测试代码如下:
<?php $url = "http://www.baidu.com/s?wd=php"; set_time_limit(0); $content = ''; try{ $result = getContentFromUrl($url); foreach($result as $key=>$value){ if($value != "#"){ $content.= $value."\n"; } } file_put_contents('url.txt',$content); }catch(Exception $e){ echo $e->getMessage(); } function getContentFromUrl($url){ if(!$url){ return null; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); $content = curl_exec($ch); if($content === false){ throw new Exception("[ curl ]:".curl_erron().":".curl_error()); } curl_close($ch); //$content = file_get_contents($url); $result = array(); preg_match_all('/<a(?: +[^>]*)? *href *= *"([^"]*)" *[^>]*?>(?:.*)<\/a>/i',$content,$result); var_dump( $result[1] ); return $result[1]; }
mysql部分:
1. 如何检验sql语句的效率索引使用情况?
解析:explain sql语句。可以从表中看出相应的结果。
更多详细的介绍可参考这篇文章:http://www.1983blue.com/index.php/posts/mysql-explain-index_1
js部分:
<form action=”?do=login” name=”login” method=”post”><input type=”text” value=”" name=”age”/></form>
如何当age的值填入18的时候,form的action变更为?do=login_bak ?
解析:简单的事件监听和js函数。
onchange的时候检测value值,如果为18.则form.login.action = ?do=login_bak.
解析:uptime ,top命令。loadavg。 proc系统。
推荐文章:http://www.flybaaa.com/help/69_1.html。讲解很清晰,很清晰。
netstat -nat |grep :1111 |wc -l
ps -ef | grep apache
解析:需要注意的是“防止盗用”与“防止盗链”是不同的概念。
为了防止被盗用,你需要做的是类如图片水印之类的东西(例如新浪博客上上传的图片会自动加上你的微博id,就是一种防盗用技术)。
怎样防止图片被盗用,可以参考本文章:http://blog.sina.com.cn/s/blog_5e3e2a6a0100e658.html
为了防止被盗链,需要做目录或文件权限设置,或者域名检测(不是本网站的域名时,或跳出提示,或显示替代图片)。apache的目录设置可以实现这个功能。
具体的细节可看:http://blog.csdn.net/mygood322/article/details/7582531。
上传目录设置一般为:一个用户一个大目录。目录下面可以分多个具体的目录。
为了防止图片重复上传,可以:
禁止短时间内多次提交按钮(js控制,点击按钮后几秒内上传按钮失效);
防止刷新提交按钮;关于这点,看到一个很简练的方式:
用 令牌机制 先生成个随机字符串,存在session里. 例如: if(!isset($_SESSION['verify'])){ $_SESSION['verify'] = gmmktime(); } 然后在 html的表单中加个隐藏字段 <input type="hidden" name="verify" value="<?=$_SESSION['verify']?>" /> 在表单提交的时候,检查提交上来的verify的值 是否等于 session里存的 if($_POST['verify']!=$_SESSION['verify']){ die('请勿重复提交'); }else{ unset($_SESSION['verify']); //做上传需要做的事情..... }
本次php面试题目基本总结完成。