PHP文件上传一些小收获

 更新时间:2016年11月25日 15:02  点击:3623
又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来。


开始觉得这玩意很简单,结果嘛惨不忍睹。用CodeIgniter的上传类来上传文件,一开始进展蛮顺利的,但发觉走到上传文件类型的时候就走不下去了。我明明添加了.torrent类型为可上传类型,结果无论我怎么传也传不上去,还提示我上传文件类型不对。汗森了,这可是货真价实的种子文件啊,难道CI只认可岛国的种子吗?

 
打开CI的上传类看代码,原来CI的UPLOAD是通过判断文件的来实现文件识别的。难怪,种子的MIME类型在一般浏览器上返回的都是二进制数据类型,看来只有自己动手改造一下了。

 
为了尽快完成项目,我直接从控制器(Controller)开始写代码。用$_FILE['file']['name']获取上传文件的文件名,然后用explode函数来获取后缀名,最后再调用CI的UPLOAD来上传文件。代码如下:

PHP代码

 代码如下 复制代码
$config['upload_path'] = './uploads/';  
$config['allowed_types'] = '*';  
$config['max_size'] = '100';  
$this->load->library('upload',$config);  
$this->load->helper('security');  
$this->load->helper('date');  
$this->load->helper('url');  
$this->load->model('bt_model','',TRUE);  
$data['source_url'] = base_url().'source';  
$data['base_url'] = base_url();  
  
  
  
$file = $_FILES['upload_file']['name'];  
$file_1 = explode('.',$file);  
$file_2 = $file_1[count($file_1)-1];  
if($file_2 <> 'torrent'){  
    echo '<script>alert("只能上传类型为torrent的种子文件");</script>';  
    echo '<script>window.location.href="'.$data['base_url'].'index.php/index/post";</script>';  
    return;  
}  
$data['type'] = xss_clean($this->input->post('type'));  
$data['name'] = xss_clean($this->input->post('name'));  
$data['space'] = xss_clean($this->input->post('space'));  
$data['username'] = xss_clean($this->input->post('username'));  
$data['time'] = mdate('%Y-%m-%d %G:%i',gmt_to_local(time(),'UP8'));  
if($data['type'] == '' || $data['name'] == '' || $data['space'] == '' || $data['username'] == ''){  
    echo '<script>alert("信息填写不完整,请重新填写");</script>';  
    echo '<script>window.location.href="'.$data['base_url'].'index.php/index/post";</script>';  
    return;  
}  
$this->upload->do_upload('upload_file');  
echo $this->upload->display_errors();  
$file = $this->upload->data();  
$data['url'] = $data['base_url'].'uploads/'.$file['file_name'];  
$this->bt_model->insert($data);  
echo '<script>alert("上传成功");</script>';  
echo '<script>window.location.href="'.$data['base_url'].'";</script>';  

原理大致是这样的,获取上传文件的文件名,然后通过explode()函数来分割文件名以获取后缀,得到后缀之后与允许上传类型做比较,最后上传。

 
讲到上传,我又想到了原来那个特别流行的MIME上传漏洞。很简单,当网站判断上传文件类型时只判断MIME类型那么就会造成上传漏洞。因为上传时服务器得到的MIME类型是从客户端发过来的,也就是说MIME类型的值是可以被用户控制的,攻击者克构造虚假的MIME类型来上传webshell。

所以判断文件类型的时候还是检测文件后缀名吧,最好只给上传目录一个可读权限,关闭执行权限,这样比较靠谱。

今天做的是个简单的表明表页面,前端我用的是Bootstrap。没办法,自己不懂美工,也只有用别人的工具。BS真的很漂亮,而且插件丰富,不愧是twitter工程师弄出来的东西。

(中文官网:http://www.bootcss.com)好的东西大家都喜欢,但是它对IE6-9的兼容几乎是0。大家也懂的,国外基本是不使用这几款浏览器了。不过在中国,IE依然占有很高的市场份额。所以,有人开发了一款叫做BSIE的Bootstrap插件,美其名曰鄙视IE,使用方法也相当简单。好像有点跑题,后端我用的是CodeIgniter,它是基于PHP的开源框架。CI是今天的正题。

 

  因为CI对于数据的过滤函数只有xss_clean(),(不知道是不是自己才疏学浅,总之没有找到其他的过滤函数)而今天的项目涉及到接收用户数据,然后提交数据库的操作。没有针对SQL语句的过滤,使得这一操作变得很危险。有点蛋蛋的忧桑,我想到的方法是改写CI的xss_clean()函数,使之具备过滤SQL注入语句的功能;一来改起来方便,二来过滤数据的时候不用嵌套两个函数。说干就干,在CI/system/core/目录下找到secure.php文件,找到xss_clean()函数的申明位置,在最后加上这么一段东西。

PHP代码

 代码如下 复制代码
$str = str_replace("_","x",$str);    
$str = str_replace("%","x",$str);    
$str = str_replace(""","x",$str);    
$str = str_replace("'","x",$str);    
$str = str_replace("select","x",$str);    
$str = str_replace("update","x",$str);    
$str = str_replace("insert","x",$str);   
$str = str_replace("set","x",$str);   
$str = str_replace("where","x",$str);   
$str = str_replace("from","x",$str);   
$str = str_replace("alert","x",$str);    
$str = str_replace("like","x",$str);   
return $str;  

 

  这样差不多能避免一般的SQL注入了。

在php中cookie和session经常是配合使用的,但是cookie安全性没有session高了,session只在服务器端而cookie在客户端,这个自然就明白它们的区别了,但它们经常用于各种登录验证,下面我来介绍。

Cookie和Session算是网站登陆验证的常用手段了。不管论坛也好,微博也好,它们都依赖于cookie和session以完成各项工作。

这里就不具体介绍Cookie和Session的概念了,我们可以简单的把它们理解为临时钥匙,用于开启不同的网络资源。
 

下面开始介绍在PHP里如何操作Cookie和Session。
 

Cookie:

  在PHP里,我们可以使用setcookie()函数来设置cookie。但特别注意,setcookie函数必须置于<html>标签之前。setcookie函数包含了一下几个参数:setcookie(name, value, expire, path, domain)。name参数是用来规定cookie的名称的,而value则是规定对应名称cookie的值,expire则是设定cookie有效期的。特别注意path和domain参数可选的。(path是规定cookie的服务器路径,而domain是规定cookie的所有域名)。


一般我们这样设置cookie

 
设置cookie

 代码如下 复制代码

<?php  
setcookie("username","Ku_Andrew",time()+3600);  
?>  

 

username就是我们cookie的名字了,而Ku_Andrew则是username的值,time()+3600就是一小时后该cookie过期。

 

现在我们用$_COOKIE来做一个实例

 
设置、读取cookie

 代码如下 复制代码

<?php  
$username = $_COOKIE['username'];  
if ($username == "")  
    {  
    setcookie("username","Ku_Andrew",time()+3600);  
    echo "we've not found your username from your cookie";  
    echo "but now we've give it to you , please refresh this page";  
    die("<a href=$PHP_SELF>kick me and refresh</a>");  
    }  
else  
    {  
    echo ("hello $usernama");  
    }  
?>  

 

如果想做出更复杂的判断,例如用户登陆等,我们可以在IF语句中的加入从数据库从检索出来的值。

 
Session:

  与Cookie不同,Session是保存在服务器上的,同时Session会随着浏览器的关闭而自动灭亡,生命周期较短。在PHP上,我们使用session_start()函数来启动session;与设置cookie相同,我们必须在<html>标签之前使用这个函数。使用这个函数之后我们就可以开始设置我们的Session变量了。方法也是极为简单:用$_SESSION数组直接定义。完成了定义,在不使用的时候为了节约服务器资源,我们要关闭它。这时可以使用unset()函数或者session_destroy()函数;unset()是解除变量,session_destroy()则是彻底终结session。下面是代码片段。

 
Session设置、读取

 代码如下 复制代码

<?php  
session_start();  
if ($_SESSION['pid'] == "")  
{  
    $_SESSION['pid'] = 1;  
}  
else  
{  
    $_SESSION['pid'] += 1;  
}  
echo "this is your $_SESSION['pid'] times watching this page";  
?>  

 
这是一个简单的网页计数器,通过设置pid来实现计数。第一次判断中,如果session为空,那么设置成一,并且读取session,反馈给用户。以后的每次访问,都会在原有session的基础上逐次加一反馈给用户。

接触PHP已经有一段时间了,今天写一篇关于PHP连接MYSQL数据库的文章,也算是自己对学习PHP与数据库的一点总结。


果文章出现错误,希望各位包涵、指出。

言归正传,对于PHP来讲,它是默认支持MYSQL的,也就是说我们不必再去手动设置ODBC来使用MYSQL了,我们所需要做的设置就是在php.ini中引入MYSQL插件。首先找到你的php.ini,编辑它,将extension = php_mysql.dll前的分号(“;”)去掉即可。这样,我们的php就可以使用MYSQL了。

 接下来我们连接mysql,mysql_connect(servername:port,username,password)就是用于连接mysql的函数,其中servername:port参数就是数据库地址以及数据库端口(默认情况下port参数为3306);username即是登陆数据库所使用的用户名,password则是对应用户的密码。由于我的数据库就在本机上所以连接时我使用以下语句。

 
连接代码

$con = mysql_connect("localhost","root","");  //$con可理解为连接号

当然我们不能让mysql一直处于连接状态,对于小型应用来说或许这不算问题,但对于大型web应用来讲这是很浪费资源的,所以用完数据库连接之后我们要关掉它。这个任务我们交给mysql_close(连接号)来完成。


开启和关闭数据库连接

 代码如下 复制代码
$con = mysql_connect("loaclhost","root","");  
$con = mysql_close($con);  

 
 
弄明白了如何连接和断开数据库,接下来就是在mysql中创建数据库,这听起来很拗口,因为同一台mysql服务器中可以允许多个数据库的存在。这里我们有两种方法来建立数据库,法一使用mysql_create_db()函数,但不建议大家使用这种方法。

 
创建数据库

 代码如下 复制代码

$con = mysql_connect("localhost","root","");  
mysql_create_db("guestbook",$con);  
mysql_close($con);  

法二,我们直接采用mysql_query()函数来执行sql语句。Create DATABASE 就是用于创建数据库的sql语句,例如Create DATABASE test,就是创建一个名为test的数据库。
 

创建数据库

 代码如下 复制代码

$con = mysql_connect("localhost","root","");    
mysql_query("Create DATABASE guestbook",$con);    
mysql_close($con);   

 

 建完数据库,我们要向数据库中添加数据表。同样是采用mysql_query()函数来执行sql语句,但不同的是之前我们要使用mysql_select_db()函数来选择我们操作的数据库。

 代码如下 复制代码

$con = mysql_connect("localhost","root","");      
mysql_query("Create DATABASE guestbook",$con);  
mysql_select_db("guestbook",$con);  
mysql_query("Create TABLE users(username varchar(15), 
password varchar(15))");      
mysql_close($con);  
/*  建表语句: Create TABLE 表明(字段名_1 字段数据类型_1,字段名_2 字段数据类型_2,......,字段名_n 字段数据类型_n)      */ 

 


在数据库中建立好表、字段等数据数据关系之后,就差实实在在的数据了。同上,使用mysql_query()函数执行添加数据的sql语句,Insert INTO 表名 (字段名_1,字段名_2,......,字段名_n) VALUES (数据_1,数据_2,......,数据_n)。

 代码如下 复制代码

 
$con = mysql_connect("localhost","root","");        
mysql_query("Create DATABASE guestbook",$con);    
mysql_select_db("guestbook",$con);    
mysql_query("Create TABLE users(username varchar(15),  
password varchar(15))");    
mysql_query("Insert INTO users (username,password) VALUES ('Ku_Andrew','123456')");      
mysql_close($con);   

现在,我们的数据库中已经有了数据,接下来我们使用select语句来进去查询。

 代码如下 复制代码
$con = mysql_connect("localhost","root","");        
mysql_query("Create DATABASE guestbook",$con);    
mysql_select_db("guestbook",$con);    
mysql_query("Create TABLE users(username varchar(15),  
password varchar(15))");   
$select = mysql_query("select * from users");  
while ($row = mysql_fetch_array($select);)  
{  
    echo $row['username'];  
    echo $row['password'];  
}  
mysql_close($con); 

  

这样,通过while循环我们就可以把users表中所有的数据全部查询出来,上面这样做不好重复利了,下面我们可以做成数据库连接类。

 代码如下 复制代码

<?php
//------------------------------------------------------------------------------------------
// ※Database()                   构造函数,数据库初始参数
// ※Select()                     查询
// ※GetRows()                    返回查询的记录总数
// ※Insert()                     插入记录
// ※Update()                     更新
// ※Delete()                     删除
// ※Halt()                       中断并显示错误信息 111Cn.Net */
//------------------------------------------------------------------------------------------
define("DATABASETYPE", "1");       //定义数据库类型:1为MySql;2为SQL Server;3为Oracle;4为Odbc
define("SERVER", "localhost");     //Host name or IP address of the database server
define("DATABASE", "dbName");   //要连接的数据库名
define("USER", "tableName");     //用于连接数据库的用户名
define("PASSWORD", "paswd");    //用于连接数据库的密码 

class Database {
    var $dbLink;                      //连接句柄
    var $result;                      //查询句柄
    var $insId;                       //Insert()成功返回AUTO_INCREMENT列的值
    var $rows;                        //返回数据数组
    var $numRows;                     //返回数据数目
    var $dbHost, $dbUser, $userPassword, $database;
    var $dbType = DATABASETYPE;
    var $msgFlag = "yes";            //yes:show the Mysql message ; no: die by show "Halted."

    function Database($dbHost = SERVER, $dbUser = USER, $userPassword = PASSWORD, $database = DATABASE) {
        switch ($this->dbType) {
            case 1:
                $this->dbLink = @mysql_pconnect($dbHost, $dbUser, $userPassword); // or die("Can't Connect to Remote Host!");
                @mysql_select_db($database, $this->dbLink); // or die ("Can't Connect to Remote Host!");
                break;
            case 2:
                break;
        }
        return true;
    }

    /* SQL:Select() 返回为false无结果 */

    function Select($table, $columns, $condition = 1) {
        $sql = "select $columns from $table where $condition ";
        $this->result = @mysql_query($sql, $this->dbLink);
        unset($this->rows);
        if ($this->result) {
            $i = 0;
            if (!($this->rows = array("$i" => @mysql_fetch_array($this->result))))
                return false;
            if (($this->numRows = @mysql_num_rows($this->result)) == 0)
                return false;
            while ($tempRows = @mysql_fetch_array($this->result)) {
                array_push($this->rows, $tempRows);
            }
        } else {
            $this->Halt($sql);
            return false;
        }
        return true;
    }

    /* SQL:GetRows() 返回查询的记录总数 */

    function GetRows($table, $condition = 1) {
        $sql = "select count(1) as count from $table where $condition";
        $this->result = @mysql_query($sql, $this->dbLink);
        if ($this->result) {
            $temp = @mysql_fetch_array($this->result);
            $this->numRows = $temp[count];
        } else {
            $this->Halt($sql);
            return false;
        }
        return $this->numRows;
    }

    /* SQL:Insert() */

    function Insert($table, $columns, $values) {
        $sql = "insert into $table ($columns) values ($values)";
        $this->result = @mysql_query($sql, $this->dbLink);
        if ($this->result)
            $this->insId = @mysql_insert_id($this->dbLink);
        else {
            $this->Halt($sql);
            return false;
        }
        return true;
    }

    /* SQL:Update() */

    function Update($table, $setings, $condition) {
        $sql = "update $table set $setings where $condition";
        $this->result = @mysql_query($sql, $this->dbLink);
        if ($this->result)
            $this->numRows = @mysql_affected_rows($this->result);
        else {
            $this->Halt($sql);
            return false;
        }
        return true;
    }

    /* SQL:Delete */

    function Delete($table, $condition) {
        $sql = "delete from $table where $condition";
        $this->result = @mysql_query($sql, $this->dbLink);
        if ($this->result)
            $this->numRows = @mysql_affected_rows($this->result);
        else {
            $this->Halt($sql);
            return false;
        }
        return true;
    }

    /* Halt():error message */

    function Halt($msg) {
        if ($this->msgFlag == "yes") {
            printf("<b>Database Query Error:</b> %s<br>n", $msg);
            printf("<b>MySql Error:</b> %s<br>n", mysql_error());
        }else
            echo "<META HTTP-EQUIV=REFRESH CONTENT='0;URL=../include/error.htm'>"; //自定一个出错提示文件
        return false;
    }
}

switch ($db->dbType) {
    case 1:
        @mysql_close();
        break;
    case 2:
        break;
}
$db = new Database();
?>

在php判断星期几其实很简单,因为我们的data函数可带参数W来获取0,1,2,3,4,5,6分别为周日到周六了,下面我们看个实例。

php日期函数date里面有个参数w代表周几

w分别表示为: 0 周日 1 周一 2 周二 … 6 周六

所以我们判断今天是周几的话  直接:

 代码如下 复制代码

$w = date('w');

//注意上面返回的都是 数字,0123456.所以如果要显示中文的星期,可以定义下面的数组就可以了。

$weekarray=array("日","一","二","三","四","五","六"); //0表示星期日

echo '周'.$weekarray[$w];

而判断某天是星期几  格式为

 代码如下 复制代码

date(‘w’,unix时间毫秒)

echo date('w',strtotime('2012-05-09 12:23:30'));

[!--infotagslink--]

相关文章

  • php读取zip文件(删除文件,提取文件,增加文件)实例

    下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
  • Jupyter Notebook读取csv文件出现的问题及解决

    这篇文章主要介绍了JupyterNotebook读取csv文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2023-01-06
  • Photoshop打开PSD文件空白怎么解决

    有时我们接受或下载到的PSD文件打开是空白的,那么我们要如何来解决这个 问题了,下面一聚教程小伙伴就为各位介绍Photoshop打开PSD文件空白解决办法。 1、如我们打开...2016-09-14
  • 解决python 使用openpyxl读写大文件的坑

    这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
  • C#实现HTTP下载文件的方法

    这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
  • SpringBoot实现excel文件生成和下载

    这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
  • C#操作本地文件及保存文件到数据库的基本方法总结

    C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
  • php无刷新利用iframe实现页面无刷新上传文件(1/2)

    利用form表单的target属性和iframe 一、上传文件的一个php教程方法。 该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失...2016-11-25
  • Php文件上传类class.upload.php用法示例

    本文章来人大家介绍一个php文件上传类的使用方法,期望此实例对各位php入门者会有不小帮助哦。 简介 Class.upload.php是用于管理上传文件的php文件上传类, 它可以帮...2016-11-25
  • php批量替换内容或指定目录下所有文件内容

    要替换字符串中的内容我们只要利用php相关函数,如strstr,str_replace,正则表达式了,那么我们要替换目录所有文件的内容就需要先遍历目录再打开文件再利用上面讲的函数替...2016-11-25
  • PHP文件上传一些小收获

    又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
  • jQuery实现简单的文件上传进度条效果

    本文实例讲述了jQuery实现文件上传进度条效果的代码。分享给大家供大家参考。具体如下: 运行效果截图如下:具体代码如下:<!DOCTYPE html><html><head><meta charset="utf-8"><title>upload</title><link rel="stylesheet...2015-11-24
  • Zend studio文件注释模板设置方法

    步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
  • AI源文件转photoshop图像变模糊问题解决教程

    今天小编在这里就来给photoshop的这一款软件的使用者们来说下AI源文件转photoshop图像变模糊问题的解决教程,各位想知道具体解决方法的使用者们,那么下面就快来跟着小编...2016-09-14
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • php文件上传你必须知道的几点

    本篇文章主要说明的是与php文件上传的相关配置的知识点。PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir、upload_max_filesize、post_max_size等选项,下面一一说明。打开php.ini配置文件找到File Upl...2015-10-21
  • ant design中upload组件上传大文件,显示进度条进度的实例

    这篇文章主要介绍了ant design中upload组件上传大文件,显示进度条进度的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-29
  • C#使用StreamWriter写入文件的方法

    这篇文章主要介绍了C#使用StreamWriter写入文件的方法,涉及C#中StreamWriter类操作文件的相关技巧,需要的朋友可以参考下...2020-06-25
  • php实现文件下载实例分享

    举一个案例:复制代码 代码如下:<?phpclass Downfile { function downserver($file_name){$file_path = "./img/".$file_name;//转码,文件名转为gb2312解决中文乱码$file_name = iconv("utf-8","gb2312",$file_name...2014-06-07
  • EXCEL数据上传到SQL SERVER中的简单实现方法

    EXCEL数据上传到SQL SERVER中的方法需要注意到三点!注意点一:要把EXCEL数据上传到SQL SERVER中必须提前把EXCEL传到服务器上.做法: 在ASP.NET环境中,添加一个FileUpload上传控件后台代码的E.X: 复制代码 代码如下: if...2013-09-23