﹤首页 > 编程技术 > php
发布时间:2016-11-25 15:02
这是一种非常简单文件上传方式。基于安全方面的考虑,您应当增加有关什么用户有权上传文件的限制。
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <meta http-equiv="Content-Language" content="zh-cn" /> </head> <body> <form action="/upload.php" method="post" enctype="multipart/form-data"> <label for="file">Filename:</label> <input type="file" name="file" id="file" /><br /> <input type="submit" name="submit" value="Submit" /> </form> <?php if($_POST){ if ( $_FILES["file"]["size"] < 2000000 ) { if ($_FILES["file"]["error"] > 0) { echo "Return Code: " . $_FILES["file"]["error"] . "<br />"; } else { echo "Upload: " . $_FILES["file"]["name"] . "<br />"; echo "Type: " . $_FILES["file"]["type"] . "<br />"; echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />"; echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />"; if (file_exists("upload/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " already exists. "; } else { move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); echo "Stored in: " . "upload/" . $_FILES["file"]["name"]; } } } else { echo "Invalid file"; } } ?> </body> </html>
第一个参数是表单的 input name,第二个下标可以是 "name", "type", "size", "tmp_name" 或 "error"。就像这样:
$_FILES["file"]["name"] - 被上传文件的名称 $_FILES["file"]["type"] - 被上传文件的类型 $_FILES["file"]["size"] - 被上传文件的大小,以字节计 $_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称 $_FILES["file"]["error"] - 由文件上传导致的错误代码
实例
首先是上传的提交页面upfile.html
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <form action="upload.php" enctype="multipart/form-data" method="POST"> <input type="hidden" name="max_file_size" value="33554432"> <input type="file" name="file"> <input type="submit" name="submit" value="上传" /> </form>
1. PHP支持HTML以POST的方法传输文件,但是form中必须声明enctype的属性="multipart/form-data",否则整个form表单将不起任何作用。
2. form表单中必须含有一个name为MAX_FILE_SIZE的隐藏域,这个隐藏域用来指定用户最大能上传的文件大小,必须声明在所有其他input标签之前。如果文件超大的话,浏览器直接就可以给出提示,不必浪费上传的时间。
下面就是上传处理文件upload.php
<?php /* 设定上传目录 */ $dest_dir='uploads'; /* 检测上传目录是否存在 */ if( !is_dir($dest_dir) || !is_writeable($dest_dir) ) { die("上传目录 ".$dest_dir." 不存在或无法写入"); } /* 设置允许上传文件的类型 */ $type=array("rar","zip","txt","c"); /* 获取上传文件信息 */ $upfile=&$HTTP_POST_FILES['file']; /* 获取文件后缀名函数 */ function fileext($filename) { return substr(strrchr($filename, '.'), 1); } /* 判断上传文件类型 */ if( !in_array( strtolower( fileext($upfile['name'] ) ),$type) ) { $text=implode(",",$type); echo "对不起,您只能上传以下类型文件: ",$text,"<br>"; } else { /* 设置文件名为"日期_文件名" */ $dest=$dest_dir.'/'.date("ymdHis")."_".$upfile['name']; /* 移动上传文件到指定文件夹 */ $state=move_uploaded_file($upfile['tmp_name'],$dest); if ($state) { print("文件上传成功!<br>"); print("文件名:".$dest."<br>"); print("上传的文件大小:".( round($upfile['size'] / 1024,2) )." KB<br>"); } else { /* 处理错误信息 */ switch($upfile['error']) { case 1 : die("上传文件大小超出 php.ini:upload_max_filesize 限制<br>"); case 2 : die("上传文件大小超出 MAX_FILE_SIZE 限制<br>"); case 3 : die("文件仅被部分上传<br>"); case 4 : die("没有文件被上传<br>"); case 5 : die("找不到临时文件夹<br>"); case 6 : die("文件写入失败<br>"); } } } ?>
PHP数组可以说非常重要的知识之一,能够在单独的变量名中存储一个或多个值。
什么是数组? 在使用 PHP 进行开发的过程中,会需要创建许多相似的变量。无需很多相似的变量,你可以把数据作为元素存储在数组中。数组中的元素都有自己的 ID,因此可以方便地访问它们。
有三种数组类型: 数值数组 带有数字 ID 键的数组 关联数组 数组中的每个 ID 键关联一个值 多维数组 包含一个或多个数组的数组 数值数组 数值数组存储的每个元素都带有一个数字 ID 键。可以使用不同的方法来创建数值数组:
例子 1
在这个例子中,会自动分配 ID 键:
例子 2
在这个例子中,我们人工分配的 ID 键:
$names[0] = "Peter";
$names[1] = "Quagmire";
$names[2] = "Joe";
可以在脚本中使用这些 ID 键:
<?php
$names[0] = "Peter"; $names[1] = "Quagmire"; $names[2] = "Joe";
echo $names[1] . " and " . $names[2] . " are ". $names[0] . "'s neighbors"; ?>
以上代码的输出:
1 Quagmire and Joe are Peter's neighbors 关联数组 关联数组,它的每个 ID 键都关联一个值。在存储有关具体命名的值的数据时,使用数值数组不是最好的做法。通过关联数组,我们可以把值作为键,并向它们赋值。
在本例中,我们使用一个数组把年龄分配给不同的人:
例子 2 本例与例子 1 相同,不过展示了另一种创建数组的方法:
$ages['Peter'] = "32"; $ages['Quagmire'] = "30"; $ages['Joe'] = "34";
可以在脚本中使用 ID 键:
echo "Peter is " . $ages['Peter'] . " years old."; ?>
以上脚本的输出:
Peter is 32 years old.
多维数组
在多维数组中,主数组中的每个元素也是一个数组。在子数组中的每个元素也可以是数组,以此类推。
例子 1 在本例中,我们创建了一个带有自动分配的 ID 键的多维数组:
$families = array ( "Griffin"=>array ( "Peter", "Lois", "Megan" ), "Quagmire"=>array ( "Glenn" ), "Brown"=>array ( "Cleveland", "Loretta", "Junior" ) );
如果输出这个数组的话,应该类似这样:
Array ( [Griffin] => Array ( [0] => Peter [1] => Lois [2] => Megan ) [Quagmire] => Array ( [0] => Glenn ) [Brown] => Array ( [0] => Cleveland [1] => Loretta [2] => Junior ) )
例子 2 让我们试着显示上面的数组中的一个单一的值:
echo "Is " . $families['Griffin'][2] .
" a part of the Griffin family?";
Is Megan a part of the Griffin family?
PHP方面的内容,就为大家简单的分享一下,希望大家在修改WordPress主题的时候有帮助。磊子也是边学边做,有很多地方自己也不是非常的了解,希望自己也有所提高。
数组元素的显示
在如上使用的无论$people[2]也好,无论$peoples['cs']也好,都只是输出已知的明确位置的数组元素值,如何快速输出所有或部分的数组元素,使用循环语句无疑是最快的方法。
<?php $people=array('name','sex','nation','birth'); for ($i=0;$i<4;$i++) echo "$people[$i] "; ?>
除了使用了解循环次数的for循环以外,还可以使用对循环次数无须要求的foreach语句。
<?php $people=array('name','sex','nation','birth'); foreach($people as $xiangmu) echo $xiangmu; ?>
数组遍历
用foreach来访问, 遍历的顺序是固定的么? 以什么顺序遍历呢? 比如:
$arr['laruence'] = 'huixinchen';
$arr['yahoo'] = 2007;
$arr['baidu'] = 2008;
foreach ($arr as $key => $val) {
//结果是什么?
}< li>
又比如:
$arr[2] = 'huixinchen';
$arr[1] = 2007;
$arr[0] = 2008;
//现在结果又是什么?
而有时我们要求更复杂的排序。如按键名排序,这里用到 ksort($arr); 函数,它会根据数组的键名排序,并维持原有的键值关系。相对应的 asort($arr); 函数,是按键值排序,且维持原有的键值关系。
同样原理,rsort(); arsort(); krsort(); 函数除了排序是按降序排列外,其它与sort(); rsort(); ksort(); 相同。 数组操作是PHP很重要的基础,希望能好好运用。
一维数组
例子
<?php function my_sort($a, $b) { if ($a == $b) return 0; return ($a > $b) ? -1 : 1; }
$people = array("Swanson" => "Joe", "Griffin" => "Peter", "Quagmire" => "Glenn", "swanson" => "joe", "griffin" => "peter", "quagmire" => "glenn");
uksort($people, "my_sort");
print_r ($people); ?>输出:
Array ( [swanson] => joe [quagmire] => glenn [griffin] => peter [Swanson] => Joe [Quagmire] => Glenn [Griffin] => Peter )
如下面这个二维数组,需要按照sort键名来排序,那么array_multisort() 就无法直接实现了:
$data[5] = array('volume' => 67, 'edition' => 2); $data[4] = array('volume' => 86, 'edition' => 1); $data[2] = array('volume' => 85, 'edition' => 6); $data[3] = array('volume' => 98, 'edition' => 2); $data[1] = array('volume' => 86, 'edition' => 6); $data[6] = array('volume' => 67, 'edition' => 7); // 准备要排序的数组 foreach ($data as $k => $v) { $edition[] = $v['edition']; } array_multisort($edition, SORT_ASC, $data); print_r($data);将输出:
Array ( [0] => Array ( [volume] => 86 [edition] => 1 )
[1] => Array ( [volume] => 67 [edition] => 2 )
[2] => Array ( [volume] => 98 [edition] => 2 )
[3] => Array ( [volume] => 85 [edition] => 6 )
[4] => Array ( [volume] => 86 [edition] => 6 )
[5] => Array ( [volume] => 67 [edition] => 7 )
)
•sort() 函数用于对数组单元从低到高进行排序。 •rsort() 函数用于对数组单元从高到低进行排序。 •asort() 函数用于对数组单元从低到高进行排序并保持索引关系。 •arsort() 函数用于对数组单元从高到低进行排序并保持索引关系。 •ksort() 函数用于对数组单元按照键名从低到高进行排序。 •krsort() 函数用于对数组单元按照键名从高到低进行排序。
我们知道, PHP去判断一个文件是否被加载, 是需要得到这个文件的opened_path的, 意思是说, 比如:
set_include_path("/tmp/:/tmp2/");
include_once("2.php");
?>
当PHP看到include_once “2.php”的时候, 他并不知道这个文件的实际路径是什么, 也就无法从已加载的文件列表去判断是否已经加载, 所以在include_once的实现中, 会首先尝试解析这个文件的真实路径(对于普通文件这个解析仅仅类似是检查getcwd和文件路径, 所以如果是相对路径, 一般是不会成功), 如果解析成功, 则查找EG(include_files), 如果存在则说明包含过了, 返回, 否则open这个文件, 从而得到这个文件的opened_path. 比如上面的例子, 这个文件存在于 “/tmp2/2.php”.
然后, 得到了这个opened_path以后, PHP去已加载的文件列表去查找, 是否已经包含, 如果没有包含, 那么就直接compile, 不再需要open file了.
1. 尝试解析文件的绝对路径, 如果能解析成功, 则检查EG(included_files), 存在则返回, 不存在继续
2. 打开文件, 得到文件的打开路径(opened path)
3. 拿opened path去EG(included_files)查找, 是否存在, 如果存在则返回, 不存在继续
4. 编译文件(compile_file)
这个在大多数情况下, 不是问题, 然而问题出在当你使用APC的时候…
在使用APC的时候, APC劫持了compile_file这个编译文件的指针, 从而直接从cache中得到编译结果, 避免了对实际文件的open, 避免了对open的system call.
然而, 当你在代码中使用include_once的时候, 在compile_file之前, PHP已经尝试去open file了, 然后才进入被APC劫持的compile file中, 这样一来, 就会产生一次额外的open操作. 而APC正是为了解决这个问题, 引入了include_once_override, 在include_once_override开启的情况下, APC会劫持PHP的ZEND_INCLUDE_OR_EVAL opcode handler, 通过stat来确定文件的绝对路径, 然后如果发现没有被加载, 就改写opcode为include, 做一个tricky解决方案.
但是, 很可惜, 如我所说, APC的include_once_override实现的一直不好, 会有一些未定义的问题, 比如:
set_include_path("/tmp");
function a($arg = array()) {
include_once("b.php");
}
a();
然后, 我们的b.php放置在”/tmp/b.php”, 内容如下:
class B {}
那么在打开apc.include_once_override的情况下, 连续访问就会得到如下错误:
Fatal error – include() : Cannot redeclare class
排除这些技术因素, 我也一直认为, 我们应该使用include, 而不是include_once, 因为我们完全能做到自己规划, 一个文件只被加载一次. 还可以借助自动加载, 来做到这一点.
你使用include_once,只能证明, 你对自己的代码没信心.
所以, 建议大家, 不要再使用include_once,不过我建义大家使用autoload和spl_autoload自动加载
(1) autoload机制概述
在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个单独的文件里,这样会很容易实现对类进行复用,同时将来维护时也很便利。这 也是OO设计的基本思想之一。在PHP5之前,如果需要使用一个类,只需要直接使用include/require将其包含进来即可。下面是一个实际的例 子:
/* Person.class.php */ <?php class Person { var $name, $age;
function __construct ($name, $age) { $this->name = $name; $this->age = $age; } } ?>
/* no_autoload.php */ <?php require_once (”Person.class.php”);
$person = new Person(”Altair”, 6); var_dump ($person); ?>
在这个例子中,no-autoload.php文件需要使用Person类,它使用了require_once将其包含,然后就可以直接使用Person类来实例化一个对象。
但 随着项目规模的不断扩大,使用这种方式会带来一些隐含的问题:如果一个PHP文件需要使用很多其它类,那么就需要很多的require/include语 句,这样有可能会造成遗漏或者包含进不必要的类文件。如果大量的文件都需要使用其它的类,那么要保证每个文件都包含正确的类文件肯定是一个噩梦。
PHP5为这个问题提供了一个解决方案,这就是类的自动装载(autoload)机制。autoload机制可以使得PHP程序有可能在使用类时才自动包含类文件,而不是一开始就将所有的类文件include进来,这种机制也称为lazy loading。
下面是使用autoload机制加载Person类的例子:
/* autoload.php */ <?php function __autoload($classname) { require_once ($classname . “class.php”); }
mysql_connect()函数
定义和用法
mysql_connect() 函数打开非持久的 MySQL 连接。
语法
mysql_connect(server,user,pwd,newlink,clientflag)
<?php $con = mysql_connect("localhost","mysql_user","mysql_pwd"); if (!$con) { die('Could not connect: ' . mysql_error()); }
// 一些代码...
mysql_close($con); ?>
下面我们来看个连接数据库实例
先建一个名为test的数据库(使用phpadmin)见下图:
然后,在该表内建一个名为 user的表,
准备工作完成,正式开始:)
<?php //connect.php $db_server="localhost";// 数据库服务器名称 $db_user="root"; // 连接数据库用户名 $db_pwd="leaf";//连接数据库密码 $db_name="test";//数据库的名字 $db=mysql_connect($db_server,$db_user,$db_pwd,$db_name); /* 面向对像 $db=new mysql($db_server,$db_user,$db_pwd,$db_name); */ if(!$db)echo "fail"; else echo "connect success" ?>
如果PHP是4.0以后版本,可以使用mysqli库,相应的代码这样写:
<?php ...... $db=mysqli_connect($db_server,$db_user,$db_pwd,$db_name); /* 面向对象 $db=new mysqli($db_server,$db_user,$db_pwd,$db_name); */ if(mysqli_connect_errno()){ echo "Error: Could not connect to database. Please try again laer."; exit; } else echo "Success!"; ?>
说明:使用了函数库mysqli,所以需要将php.ini文件中的extension=php.mysqli 打开
通常,我们将代码前面的几行单独放在一配制文件中,这里取名为 db_config.php
<?php //db_config.php $db_server="localhost";// 数据库服务器名称 $db_user="root"; // 连接数据库用户名 $db_pwd="leaf";//连接数据库密码 $db_name="test";//数据库的名字 ?>
如此一来,最初的那个连接测试代码就成了这样的:
<?php // connect.php require_once(“db_config.php”);//包含配置文件 $db=mysql_connect($db_server,$db_user,$db_pwd,$db_name); //同样也可以用面向对像的语法 if(!$db)echo "fail"; else echo "connect success" ?>