直接用php的header发送404错误页面的方法实例

 更新时间:2016年11月25日 15:38  点击:1727
在开发网站的时候,有时我们为了友好的提示用户输入的网址不存在,用设置一个 404 错误页面。设置 404 还有一个好处就是防止恶意用户猜测你的url参数。本文我们来讲讲用php及apache设置404错误页面的方法。

在php程序中,我们也经常需要考虑如何用php实现页面404跳转的写法,下面作者将如何用php进行404转向的写法和大家分享一下!

 代码如下 复制代码
// 直接输出页面错误信息
@header("http/1.1 404 not found");
@header("status: 404 not found");
echo 'echo 404';
exit();



或者:

 代码如下 复制代码
// 跳转到错误页面,推荐使用这种方法
// 注意include文件的路径不能是http网络路径
@header("http/1.1 404 not found");
@header("status: 404 not found");
include("/404.html");
exit();




我们也可以直接在 apache 设置 404 错误页面,具体定义方法如下:
 
在网站的根目录下新建一个 .htaccess 文件,然后在该文件中加入如下内容即可:

 代码如下 复制代码
ErrorDocument 404 http://www.phpernote.com/404.html




查看404是否设置成功可以利用 firefox 的 firebug 插件来查看,具体查看方法如下:

在已经安装firebug的情况下,用firefox浏览器打开要检查404状态码的页面,点击右下角小虫的图标,启动"网络"标签,依次打开"网络–所有/html–headers";如果一切正常,你就可以看到包括headers、响应在内的各项页面参数了。

在开发中验证邮箱、url、数字是我们常用的一些例子,下面整理了两个不同站长写的验证邮箱、url、数字程序,大家有兴趣可参考一下。

例子

 代码如下 复制代码

public static function isEmail( $email )

{

return preg_match("/^([a-z0-9]*[-_\.]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\.][a-z]{2,4}([\.][a-z]{2})?$/i" , $email  );
}

public static function isNumber( $num )
{
return is_numeric( $num );
}

public static function isUrl( $url , $preg = false )
{
if( $preg )
{
$status = preg_match ( "/^([^:\/\/])+\:\/\/[\w-]+\.[\w-.\?\/]+$/" , $url );
}
else
{
$status =  filter_var( $url , FILTER_VALIDATE_URL );
}

return $status;
}

补充:利用php自带函数来操作。

php验证邮箱

 代码如下 复制代码

<?php
$email = 'fengdingbo@gmail.com';                                               
$result = filter_var($email, FILTER_VALIDATE_EMAIL);
var_dump($result); // string(20) "fengdingbo@gmail.com"

php验证url地址

 代码如下 复制代码

<?php
$url = "http://www.111cn.net";
$result = filter_var($url, FILTER_VALIDATE_URL);
var_dump($result); // string(25) "http://www.111cn.net"

php验证ip地址

 代码如下 复制代码

<?php
$url = "192.168.1.110";                                                        
$result = filter_var($url, FILTER_VALIDATE_IP);
var_dump($result); // string(13) "192.168.1.110"
// 该方法也可以用来验证ipv6。
$url = "2001:DB8:2de::e13";                                                    
$result = filter_var($url, FILTER_VALIDATE_IP);
var_dump($result); // string(17) "2001:DB8:2de::e13"

在网站上,我们要想象每个访问者都是恶心的,这样才能整出更安全的网站。下面是高手整理的php+mysql安全方案,对于初学都特别有用。

1 不要依赖于服务器端的magic_quotes,虽然他们默认都是打开的(magic_quotes_gpc)

将下面两个关闭

ini_set("magic_quotes_runtime", 0);
ini_set("magic_quotes_sybase", 0);

全部自己手工对所有变量添加magic_quotes,就是添加addslashes

代码如下:

function stripslashes_deep($value){
    $value = is_array($value) ?
    array_map('stripslashes_deep', $value) :
    stripslashes($value);
    return $value;
}

function strip_slashes(){
    // If already slashed, strip.
    //把原有的slash去掉,重新添加自己的magic_quotes
    if ( get_magic_quotes_gpc() ) {
        $_GET    = stripslashes_deep($_GET);
        $_POST   = stripslashes_deep($_POST  );
        $_COOKIE = stripslashes_deep($_COOKIE);
        $_SERVER = stripslashes_deep($_SERVER);
        $_REQUEST = stripslashes_deep($_REQUEST);
    }
    $_GET    = add_magic_quotes($_GET   );
    $_POST   = add_magic_quotes($_POST  );
    $_COOKIE = add_magic_quotes($_COOKIE);
    $_SERVER = add_magic_quotes($_SERVER);
    $_REQUEST = add_magic_quotes($_REQUEST);
}

strip_slashes();

 
显示的时候全部stripslashes还原,虽然这很麻烦,不过如果你有一个模板引擎,可以在变量赋值的时候,统一作这个事情,

例如:

function assign($var, $value = '') {
  if (is_array($var)) {
   foreach ($var as $k => $v) {
    $this->vars[$k] = stripslashes_deep($v);
   }
  } else {
   $this->vars[$var] = stripslashes_deep($value);
  }
 }


这样可以避免' " 等符号,下面还会有说明

2 对于用户名这样的字段,输入时候,检查不允许有空格,而且必须是字母数字下划线或划线这四种,用正则检查

还有诸如结点名,菜单名,角色名这些不需要用' " 的,一定要在录入之前就检查,或者用替换为空

3 所有ID为数字的变量,必须检查是否为数字,并将变量强制转换成数字

如果ID是前面带0的或者字符型的,可用编码规则对其进行检查,例如全是数字的正则

4 对于php的mysql函数,由于天生一次只能执行一条语句,即;不会自动断。所以无法通过追加语句实现注入,只可能通过将语句插入到变量中来起作用注入,所以对于delete ,select,update都可能有破坏作用。

例如:

delete from tbl_users where user_id = 'admin' 变成 delete from tbl_users where user_id = 'admin or user_id<>'0',即在输入栏为:admin or user_id<>'0

所以对于变量参数:
不该有空格的,空格要去掉
该位数字的,一定要转换成数字
有编码规则的,一定要检查编码规则
有长度限制的一定要加入长度限制
绝对不会有注入语句的,就筛查sql关键字
将一些危险字符进行替换,例如用“代替",空格用%20代替,特殊字符转成html等等
当然用addslashes还是有明显效果的,对于php来说,要想在变量中插入条件,必须通过'来完成,所以这一招可以彻底断了所有企图
 
5 apache,php,mysql不要以系统用户运行

6 连接mysql不要用root

7 系统的所有错误信息必须关闭或者屏蔽

8 屏蔽非主流浏览器的user-agent

9 记录所有的sql操作和用户ip,如果发现危险语句,可以立刻屏蔽该IP,例如3天
  如果是用户登录后,有危险sql注入的语句,直接删除该用户,同时屏蔽IP

10 对于验证码要可以采用使用中文,变换字符串样式,必须点击弹出等方法

11 如果还是不安全,就要像电子银行那样,用U盾和专用控件了

session是一个用来可跨页面并且只在服务器上运行的全局变量了,它的作用常用于数据的安全验证了,下面小编整理了一篇php中利用redis存储session实例,大家有兴趣可进来看看。

phpinfo,可以看到session存储,可以使用files user memcache redis,使用数据库存储session的好处是较之文件存储,在大用户量下速度更快,性能更优,而且如果做分布式系统,肯定是需要使用数据库存储session的。这里总结下使用redis存储session的两种方式
使用mysql存储session大家应该使用过,session生命周期的原理其实就是session.gcprobability,session.gcdivisor这两个参数和最大生命时间决定的。每次php请求,有一定几率触发session的检测机制。我们使用session_setsavehandler,是可以重定义session的行为的。这里有两种方式实现redis存储session

代码实例1:

 代码如下 复制代码

<?php
ini_set('session.gc_maxlifetime', 3600);
ini_set("session.save_handler","redis");
ini_set("session.save_path","tcp://127.0.0.1:6379?auth=authpwd");
session_start();
//$_SESSION['session'] = 'this is session content!';
echo $_SESSION['session'];
echo session_id().'<br/>';
 
$redis = new redis();
$redis->connect('127.0.0.1', 6379);
//redis用session_id作为key并且是以string的形式存储
echo $redis->get('PHPREDIS_SESSION:' . session_id());
?>

代码实例2:

 代码如下 复制代码
<?php
 
class RedisSessionHandler{
    public $ttl = 1800; // 30 minutes default
    protected $db;
    protected $prefix;
    public function __construct($db, $prefix = 'PHPSESSID1:',$time=1800) {
        $this->db = $db;
        $this->prefix = $prefix;
        $this->ttl =  $time;
    }
    function _open()
    {
        //
    }
 
    function _close()
    {
        $this->db = null;
        unset($this->db);
    }
 
    function _read($id)
    {
        $id = $this->prefix . $id;
        $sessData = $this->db->get($id);
        $this->db->expire($id, $this->ttl);
        return $sessData;
    }
 
    function _write($id, $data)
    {
        $id = $this->prefix . $id;
        $this->db->set($id, $data);
        $this->db->expire($id, $this->ttl);
    }
 
    function _destroy($id)
    {
        $this->db->del($this->prefix . $id);
    }
 
    function _clean($max)
    {
        //
    }
}
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$redis->select(1);
$SESSION_ID_PREFIX = 'RSID:';
$SESSION_MAX_TIME  = 1440;
ini_set('session.gc_maxlifetime',$SESSION_MAX_TIME);
$sessHandler = new RedisSessionHandler($redis,$SESSION_ID_PREFIX,$SESSION_MAX_TIME);
session_set_save_handler(
    array($sessHandler, '_open'),
    array($sessHandler, '_close'),
    array($sessHandler, '_read'),
    array($sessHandler, '_write'),
    array($sessHandler, '_destroy'),
    array($sessHandler, '_clean')
);
 
session_start();
echo session_id();
echo $_SESSION['name']='zhangcunchao';

> 第一种方式比较简单,但是无法选择库号,并且session_id的前缀信息比较难以控制,但是此方法也可以直接修改php配置文件,使所有程序的session使用redis
> 第二种方式相对麻烦一点,但是使用起来比方方便
> 网上有说并发一致性问题,所有的哈希算法肯定都会有这样的问题,不过可以通过ip前缀哈希组合来一定程度解决

网站经常要用到下载远程图片的功能,有时还要下载.doc文档,所以就用php开发了一个下载远程文件的类,这个类支持断点续传下载,源代码中有具体的注释及使用说明案例。

程序主要是使用 HTTP 协议下载文件,HTTP1.1协议必须指定文档结束后关闭链接,否则读取文档时无法使用feof判断结束,可以有两种使用方法,具体请下载查看源码。

 代码如下 复制代码
<?php
/**
 * 下载远程文件类支持断点续传
 */
class HttpDownload {
    private $m_url = "";
     private $m_urlpath = "";
     private $m_scheme = "http";
     private $m_host = "";
     private $m_port = "80";
     private $m_user = "";
     private $m_pass = "";
     private $m_path = "/";
     private $m_query = "";
     private $m_fp = "";
     private $m_error = "";
    private $m_httphead = "" ;
    private $m_html = "";
 
    /**
     * 初始化
     */
    public function PrivateInit($url){
        $urls = "";
        $urls = @parse_url($url);
        $this->m_url = $url;
        if(is_array($urls)) {
            $this->m_host = $urls["host"];
            if(!empty($urls["scheme"])) $this->m_scheme = $urls["scheme"];
            if(!empty($urls["user"])) $this->m_user = $urls["user"];
            if(!empty($urls["pass"])) $this->m_pass = $urls["pass"];
            if(!empty($urls["port"])) $this->m_port = $urls["port"];
            if(!empty($urls["path"])) $this->m_path = $urls["path"];
            $this->m_urlpath = $this->m_path;
            if(!empty($urls["query"])) {
                 $this->m_query = $urls["query"];
                 $this->m_urlpath .= "?".$this->m_query;
             }
          }
    }
 
    /**
    * 打开指定网址
    */
    function OpenUrl($url) {
        #重设各参数
        $this->m_url = "";
        $this->m_urlpath = "";
        $this->m_scheme = "http";
        $this->m_host = "";
        $this->m_port = "80";
        $this->m_user = "";
        $this->m_pass = "";
        $this->m_path = "/";
        $this->m_query = "";
        $this->m_error = "";
        $this->m_httphead = "" ;
        $this->m_html = "";
        $this->Close();
        #初始化系统
        $this->PrivateInit($url);
        $this->PrivateStartSession();
    }

    /**
    * 获得某操作错误的原因
    */
    public function printError() {
        echo "错误信息:".$this->m_error;
        echo "具体返回头:<br>";
        foreach($this->m_httphead as $k=>$v) {
            echo "$k => $v <br>rn";
        }
    }
 
    /**
    * 判别用Get方法发送的头的应答结果是否正确
    */
    public function IsGetOK() {
        if( ereg("^2",$this->GetHead("http-state")) ) {
            return true;
        } else {
            $this->m_error .= $this->GetHead("http-state")." - ".$this->GetHead("http-describe")."<br>";
            return false;
        }
    }
   
    /**
    * 看看返回的网页是否是text类型
    */
    public function IsText() {
        if (ereg("^2",$this->GetHead("http-state")) && eregi("^text",$this->GetHead("content-type"))) {
            return true;
        } else {
            $this->m_error .= "内容为非文本类型<br>";
            return false;
        }
    }
    /**
    * 判断返回的网页是否是特定的类型
    */
    public function IsContentType($ctype) {
        if (ereg("^2",$this->GetHead("http-state")) && $this->GetHead("content-type") == strtolower($ctype)) {
            return true;
        } else {
            $this->m_error .= "类型不对 ".$this->GetHead("content-type")."<br>";
            return false;
        }
    }
   
    /**
    * 用 HTTP 协议下载文件
    */
    public function SaveToBin($savefilename) {
        if (!$this->IsGetOK()) return false;
        if (@feof($this->m_fp)) {
            $this->m_error = "连接已经关闭!";
            return false;
        }
        $fp = fopen($savefilename,"w") or die("写入文件 $savefilename 失败!");
        while (!feof($this->m_fp)) {
            @fwrite($fp,fgets($this->m_fp,256));
        }
        @fclose($this->m_fp);
        return true;
    }
   
    /**
    * 保存网页内容为 Text 文件
    */
    public function SaveToText($savefilename) {
        if ($this->IsText()) {
            $this->SaveBinFile($savefilename);
        } else {
            return "";
        }
    }
   
    /**
    * 用 HTTP 协议获得一个网页的内容
    */
    public function GetHtml() {
        if (!$this->IsText()) return "";
        if ($this->m_html!="") return $this->m_html;
        if (!$this->m_fp||@feof($this->m_fp)) return "";
        while(!feof($this->m_fp)) {
            $this->m_html .= fgets($this->m_fp,256);
        }
        @fclose($this->m_fp);
        return $this->m_html;
    }
   
    /**
    * 开始 HTTP 会话
    */
    public function PrivateStartSession() {
        if (!$this->PrivateOpenHost()) {
            $this->m_error .= "打开远程主机出错!";
            return false;
        }
        if ($this->GetHead("http-edition")=="HTTP/1.1") {
            $httpv = "HTTP/1.1";
        } else {
            $httpv = "HTTP/1.0";
        }
        fputs($this->m_fp,"GET ".$this->m_urlpath." $httpvrn");
        fputs($this->m_fp,"Host: ".$this->m_host."rn");
        fputs($this->m_fp,"Accept: */*rn");
        fputs($this->m_fp,"User-Agent: Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.2)rn");
        #HTTP1.1协议必须指定文档结束后关闭链接,否则读取文档时无法使用feof判断结束
        if ($httpv=="HTTP/1.1") {
            fputs($this->m_fp,"Connection: Closernrn");
        } else {
            fputs($this->m_fp,"rn");
        }
        $httpstas = fgets($this->m_fp,256);
        $httpstas = split(" ",$httpstas);
        $this->m_httphead["http-edition"] = trim($httpstas[0]);
        $this->m_httphead["http-state"] = trim($httpstas[1]);
        $this->m_httphead["http-describe"] = "";
        for ($i=2;$i<count($httpstas);$i++) {
            $this->m_httphead["http-describe"] .= " ".trim($httpstas[$i]);
        }
        while (!feof($this->m_fp)) {
            $line = str_replace(""","",trim(fgets($this->m_fp,256)));
            if($line == "") break;
            if (ereg(":",$line)) {
                $lines = split(":",$line);
                $this->m_httphead[strtolower(trim($lines[0]))] = trim($lines[1]);
            }
        }
    }
   
    /**
    * 获得一个Http头的值
    */
    public function GetHead($headname) {
        $headname = strtolower($headname);
        if (isset($this->m_httphead[$headname])) {
            return $this->m_httphead[$headname];
        } else {
            return "";
        }
    }
   
    /**
    * 打开连接
    */
    public function PrivateOpenHost() {
        if ($this->m_host=="") return false;
        $this->m_fp = @fsockopen($this->m_host, $this->m_port, &$errno, &$errstr,10);
        if (!$this->m_fp){
            $this->m_error = $errstr;
            return false;
        } else {
            return true;
        }
    }
   
    /**
    * 关闭连接
    */
    public function Close(){
        @fclose($this->m_fp);
    }
}

#两种使用方法,分别如下:

#打开网页
$httpdown = new HttpDownload();
$httpdown->OpenUrl("http://www.google.com.hk");
echo $httpdown->GetHtml();
$httpdown->Close();


#下载文件
$file = new HttpDownload(); # 实例化类
$file->OpenUrl("http://www.ti.com.cn/cn/lit/an/rust020/rust020.pdf"); # 远程文件地址
$file->SaveToBin("rust020.pdf"); # 保存路径及文件名
$file->Close(); # 释放资源
?>
[!--infotagslink--]

相关文章

  • 404错误是什么 404错误怎么解决

    403错误是网站访问过程中,常见的错误提示。资源不可用,服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致,比如IIS或者apache设置了访问权限...2017-01-22
  • php中header自定义404状态错误页面

    404页面就是一个告诉搜索引擎这个页面不存在了,同时也提示用户可以选择其它的操作了,下面我来给没有apache操作权限朋友介绍php中自定义404页面的操作方法。 方法一...2016-11-25
  • IIS自定义404错误页避免暴露.NET网站路径信息

    这篇文章主要介绍了IIS自定义404错误页避免暴露.NET网站路径信息,在输入非.aspx页面时,显示默认404页面,暴露站点路径信息,本文就给出了一个解决方法,需要的朋友可以参考下...2016-01-27
  • 用php定制404错误页面,并发信给管理员的程序

    如果您的用户找不到他要的页面,如何给他一个友好的答复,并且你也知道发生了这个错误呢,看看下面这段程序,是用来定制404错误页面和发通知给网管的好东西。---teaman翻译...2016-11-25
  • 网站错误页面与无效页面处理技巧

    关于网站错误页面与无效页面处理有很多的一些小技巧了,如果处理的好我们可以对网站权重有少小的提升哦,如果处理不好那对网可能负面影响哦,下面一起来看看如何处理这些错...2016-10-10
  • php header 404错误包含文件出现乱码解决办法

    本文章来给大家介绍php header 404错误包含文件出现乱码解决办法,有碰到此类问题的同学可进入参考参考。 通常在通过php判断一个不存在的资源(比如category、produc...2016-11-25
  • 如何让apache支持.htaccess并设置404错误页

    如何让apache支持.htaccess,今天我在看seo 优化时发现的一个问题,就是定义页面的404错误对网站优化有一点的好处,所以我也要把自己主机上的找不到的页面设置到这里来,下面就...2016-01-28
  • php header 404跳转错误页面实例

    404页面是一种友好的错误提示页面,在php中我们可以利用php,apache,hatcess三种方法来实现向浏览器发送404错误页面状态,下面我来介绍其它的php header函数实现404错误页...2016-11-25
  • ASP.NET MVC自定义错误页面真的简单吗?

    ASP.NET MVC自定义错误页面真的简单吗?这篇文章主要介绍了ASP.NET MVC自定义错误页面,感兴趣的小伙伴们可以参考一下...2021-09-22
  • ASP.NET MVC中异常处理&自定义错误页详析

    当ASP.NET MVC程序出现了异常,怎么处理更加规范?下面这篇文章主要给大家介绍了关于ASP.NET MVC中异常处理&自定义错误页的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起学习学习吧。...2021-09-22
  • 在ASP.NET Core中显示自定义的错误页面

    大家在用浏览器访问服务器时,不同情况下会返回不同的信息。服务器发生错误就会返回错误信息,我们最熟悉的就是404错误页面,但是这里我想和大家分享下在ASP.NET Core中如何显示自定义的500或404错误页面,有需要的朋友们可以参考借鉴,下面来一起看看吧。...2021-09-22
  • Laravel 5.1自定义500错误页面的例子

    Laravel 5.1中500错误是程序错误,程序错误一定是系统自带的500错误,如果我们想自定义的话可以和小编来看看如何做。 编辑PHP文件app/Exceptions/Handler.php内容如...2016-11-25
  • SpringBoot2.3定制错误页面的方法示例

    这篇文章主要介绍了SpringBoot2.3定制错误页面的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-12
  • 404错误页面需要注意的几点事项

    在我们日常运营网站的时候,相信各位站长都会碰到这种状况,那就是经常因为改动栏目或者文件名称,导致站内出现大量的无效链接,而这种链接又是存在但是却打不开的,因此这对搜...2016-10-10
  • .net中自定义错误页面的实现升级篇

    这篇文章主要给大家介绍了关于.net中自定义错误页面实现的相关资料,这篇文章是之前的升级篇,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • IIS部署asp.net报404错误的解决方法

    进行IIS部署asp.net时报404错误,解决方法可以通过手动往IIS注册.net环境,具体实现如下,有类似情况的朋友可以参考下哈...2016-01-27
  • 直接用php的header发送404错误页面的方法实例

    在开发网站的时候,有时我们为了友好的提示用户输入的网址不存在,用设置一个 404 错误页面。设置 404 还有一个好处就是防止恶意用户猜测你的url参数。本文我们来讲讲用p...2016-11-25
  • php header()实现程序404错误状态

    本文章来告诉你如何利用程序实现php 404信息的发送,有需要的同学可以参考一下下哈。 针对apache配置中的ErrorDocument 404 /404.php功能,把nginx配置中的 ...2016-11-25
  • 自定义404错误页

    目录 1. What is 404 什么是404 2. 创建一个。htaccess文件 3. 在custom404页 4. 例如custom404页 什么是404。 .您有多个看到404 1 brazillian时候对...2016-09-20
  • apache和.htaccess设置404错误页面方法

    为Apache Server设置 404错误页面的方法很简单,只需在.htaccess 文件中加入如下内容即可: 代码如下 复制代码 ErrorDocument 404 /notfound.php ...2016-01-28