2012年12月29日星期六

防止图片盗链

    所谓盗链是指服务提供商自己不提供服务的内容,而是通过技术手段直接在自己的网站上向最终用户提供其他服务商的服务内容,以骗取用户的浏览和点击率。受益者不提供资源或提供很少的资源,而真正的服务提供商却得不到任何的收益。像图片、视频等这些比较大的文件都有可能成为被盗的对象。一旦文件被盗,就会增加服务器的流量,影响网站的访问速度。虽然我们不能100%的保护这些文件不被别人盗用,但可以通过 HTTP Referer 进行限制。使用 Apache 可以很方便地进行设置。假设主机域名为 www.example.com,在文件 .htaccess 中的配置如下:
 
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$ [NC]
RewriteCond %{HTTP_REFERER} ! http://www.example.com [NC]
RewriteCond %{HTTP_REFERER} ! http://www.google.cn [NC]
RewriteCond %{HTTP_REFERER} ! http://www.baidu.com [NC]
RewriteRule .*\.(gif|jpg)$ http://www.example.com/default.jpg [R,NC,L]

    该配置说明说下:

  •     RewriteCond %{HTTP_REFERER} !^$ [NC]
    允许 HTTP_REFERER 为空时访问,即允许用户在浏览器地址栏中直接输入图片地址时显示图片。一般来说这个选项是可选的,建议这样设置。如果将 HTTP_REFERER 强制限制不能为空,那么当用户通过代理服务器访问时,可能会导致一些问题。

  •     RewriteCond %{HTTP_REFERER} ! http://www.example.com [NC]
    设置允许访问的 HTTP_REFERER 来源,包括自身站点,以及 Baidu、Google、Yahoo!等

  • RewriteRule .*\.(gif|jpg)$ http://www.example.com/default.jpg [R,NC,L]
    设置图片被盗链时用于替换的图片,如果有图片被盗链,显示的是 default.jpg。注意,默认图片所在的路径最好跟配置文件不在同一目录下,图片越小越好。如果不想设置替换图片,可以使用下面的语句:

RewriteRule .*\.(gif|jpg)$ - [F]

NC、R、L、F 标记解释

NC:不区分大小写
R: 强制重定向
L:立即停止重写操作
F:强制禁止URL

2012年12月25日星期二

用 jQuery 覆盖 alert、confirm 函数的样式

/**
 * 覆盖默认的alert样式
 * @param message 要显示的内容
 * @param title 标题
 */
function alert(messagetitle,width,height{
    var title title || "提示";
    var width width || "300";
    var height height || "180";
    var obj $('div[id=dialog_alert]').size($('#dialog_alert'$('<div/>'{
        id "dialog_alert"
    });
  
    if ($.ui.dialog{
        if (obj.dialog("isOpen"){
            obj.dialog("close");
        }
        obj.html(message).dialog({
            title title,
            width:width,
            height:height,
            close:function(){
                $(this).dialog('destriy');
            }
        });
    else {
        alert(message);
    }
}
/**
 * 使用jquery ui 模拟javascript confirm功能
 
 * @param string
 *            message 内容
 * @param function
 *            callback 点击确认执行的函数
 * @param function
 *            closeCallback 点击取消执行的函数
 * @return boole false
 */
function myConfirm(messagecallbackcloseCallback{
    if (!$.isFunction(callback){
        try{
            console.error('第二个参数请传递一个函数');
        }catch(e){}
    
        return false;
    }
    if (!$('#dialog-follow').length{
        $('body').append('<div id="dialog-follow"></div>"');
    }
    if ($.isFunction($("#dialog-follow").dialog){
        $("#dialog-follow").dialog({
            width 300,
            modal true,
            resizable false,
            title '温馨提示',
            buttons {
                "确定" function({
                    callback();
                    $(this).dialog("close");
                },
                "取消" function({
                    $(this).dialog("close");
                    if ($.isFunction(closeCallback){
                        closeCallback();
                    }
                }
            }
        });
        $("#dialog-follow").html(message);
    else {
        if (confirm(message){
            callback();
        }
    }
    return false;
}

2012年12月19日星期三

PHP 仿百度文库


1.安装最新版本的OpenOffice


关闭 OpenOffice 程序。打开命令行,进入 OpenOffice 的主目录,键入以下命令。
soffice -headless -accept="socket,port=8100;urp;"

2.下载 JDK

配置 JAVA_HOME 环境变量
  在下一步安装的 JODConverter 要用到 Java。

3.下载  JODConverter

JODConverter是一个JavaOpenDocument文件转换器,可以进行许多文件格式的转换。它依赖于OpenOffice.org或者LibreOffice提供的服务来进行转换,它能将Microsoft Office文档(WordExcelPowerPoint)转换为PDF格式。转成PDF 文档。

<?php
exec('java -jar D:/wamp/bin/apache/Apache2.2.17/htdocs/jodconverter-2.2.2/lib/jodconverter-cli-2.2.2.jar D:\wamp\bin\apache\Apache2.2.17\htdocs\a.doc D:\wamp\bin\apache\Apache2.2.17\htdocs\a.pdf',$output);
print_r($output);
?>

4.安装最新版本的 swftools 工具。

SWFTools工具包中的PDF2SWF工具可用来将PDF格式文件转换成SWF格式。

<?php
exec('"D:\Program Files\SWFTools\pdf2swf.exe" "'.$uploaddir.$time.'.pdf" "-s  poly2bitmap&zoom=72&framerate=15&jpegquality=75&pages=1- " "-o" "'.$uploaddir.$time.'.swf" "-T" "9" "-f"');
?>

5.下载 FlexPaper

FlexPaper是一个开源轻量级的文档浏览组件,被设计和比如PDF2SWF库(包含于SWFTools)一起工作,使得在网页上,Adobe Flex以及别的基于Flash的应用程序中显示和交互PDF文件成为可能。即,使得在没有安装PDF阅读器软件的情况下浏览PDF文件成为可能。FlexPaper项目同时提供了Flex库和独立的Flash版本。

2012年12月7日星期五

MySQL 5.5 主从复制概述

    主从复制功能通过在主服务器和从服务器之间切分处理客户查询的负荷,可以得到更好的客户响应时间 SELECT 查询可以发送到从服务器,以降低主服务器的查询处理负荷。修改数据的语句仍然发送到主服务器,以使主、从服务器保持同步。如果非更新查询为主(如 SELECT 查询),该负载均衡策略很有效。

    MySQL 主从复制优点如下:

  • 增长健壮性。主服务器出现问题时,切换到从服务器作为备份。
  • 优化响应时间。不要同时在主从服务器上进行更新,这样可能引起冲突。
  • 在从服务器备份过程中,主服务器继续处理更新。


主从复制工作原理


    主从复制通过 3 个过程实现,其中一个过程发生在主服务器上,另外两个过程发生在从服务器上。具体情况如下:


  1. 主服务器将用户对数据库更新的操作以二进制格式保存到 Binary Log 日志文件中,然后由 Binlog Dump 线程将 Binary Log 日志文件传输给从服务器。
  2. 从服务器通过一个 I/O 线程将主服务器的  Binary Log 日志文件中的更新操作复制到一个叫 Relay Log 的中继日志文件中。
  3. 从服务器通过另一个 SQL 线程将 Relay Log 中继日志文件中的操作依次在本地执行,从而实现主从之间数据的同步。

  主从复制详细过程如图所示

主从复制过程

(1)BinLog Dump 线程

    BinLog Dump 线程运行在主服务器上,主要工作是把 Binary Log 二进制日志文件的数据发送给从服务器。

    使用SHOW PROCESSLIST 语句查看该线程是否正在运行。

(2)I/O 线程

    从服务器执行 START SLAVE 语句后,创建一个 I/O 线程。此线程运行在从服务器上,与主服务器建立连接,然后向主服务器发出更新请求。之后,I/O 线程将主服务器发送的更新操作复制到本地 Relay Log 日志文件中。

    使用 SHOW SLAVE STATUS 语句查看 I/O 线程状态。

 (3)SQL 线程

    SQL 线程运行在从服务器上,主要工作是读取 Relay Log 日志文件中的更新操作,并将这些操作依次执行,从而使主从服务器数据得到同步。

   

主从复制详述

    MySQL 服务器之间的复制是基于二进制日志机制的。主机的数据库实例会把更新和变化的事件写入二进制日志。根据数据库的设置,二进制日志被存储为不同的日志格式。从服务器根据配置从主服务器那里读取二进制日志,然后在本地数据库执行相应的二进制日志事件。

    在复制过程中,主机是被动的。一旦启用了二进制日志,所有的语句都会被记录进里面。每一台从服务器都会接受一份二进制日志副本,从服务器决定二进制日志哪些语句需要被执行;你不应该在主服务器配置只记录某一类的事件。如果你没有指定的话,在主服务上二进制事件在从服务器都会被执行。如果有需要的话,你可以在从服务器上指定那些应用于特殊的数据库或者表事件被执行。

    每一台从服务器都保存有一条二进制日志坐标的记录:文件名和要从主服务器读取和处理的位置。这意味着多台从服务器能同时连接主机和读取同一个二进制日志不同的部分。因为这个过程是由从服务器处理,单台从服务器连接或者断开主服务器的连接都不会影响主服务器的操作。由于每台从服务器都会记住执行到二进制日志的哪个位置,所以即使断开与主服务器的连接,然后再次连接,都会从上次断开的位置读取二进制日志。

    主服务器和从服务器必须配置成唯一的ID。另外,每台从服务器必须配置主服务的主机名、日志名称和读取日志相应的位置。这些详细的配置可以在从服务器上的会话中用 CHANGE MASTER TO  语句来控制。这些配置信息都保存在从服务器的文件 master.info 中。

2012年12月6日星期四

解决 Yii 1.12 中 Session 丢失的问题


    Session 丢失的问题在运用一些框架来开发比较常见。原因是你对框架 Session 的机制不是很了解,它有可能运用了自己的一套机制。

    情况一般是用 header 跳转后才发生的,因为在 header 之前还能够成功打印出来。

    一般 Session 跨页面丢失的问题有以下几种情况:

    1.客户端禁用 Cookie 。因为 Session 默认是基于 Cookie 的,因为找不到相应的 Cookie,所以 Session 会为空。

    2.你在给 Session 赋值时,前面已经调用了 session_write_close() 函数。在原页面虽然能够成功打印,但是并没有成功保存 Session。

    而这2中情况在 Yii 都不是,打开文件 yii\framework\web\auth\CWebUser.php  #700

     Yii::app()->getSession()->regenerateID(true);

    把这个语句注释掉就可以了。它默认调用了PHP 自带的一个函数

     bool session_regenerate_id [bool delete_old_session] )


    按常理来说是不会出现 Session 丢失问题的。这可能和我的配置或者它内部实现 Seesion 的机制有关系。

    你还可以查看PHP 手册 《Session 会话处理函数》 一章,了解更多详情。