ρεйg's profile简洁的想法PhotosBlogLists Tools Help

Blog


    2/14/2006

    PHPMore Vol6

    《PHPMore》Vol6 终于在情人节发布了,祝More的编辑们节日快乐。

  • 什么是Web 2.0
  • prototype.js开发笔记
  • Tips:用prototype写Ajax网站
  • 构建跨浏览器的XML+XPath数据岛应用
  • 如何创建Rss2.0文档
  • 小巧灵活的AJAX开发库-SACK
  • Ajax in CakePHP
  • 轻轻松松做拖动
  • 点击下载《PHP&MORE》电子杂志第六期。
  • 投稿信箱EasyChen@Gmail.com
  • 11/22/2005

    自己编写的一个PHP单文件或多文件上传类

    看到网上有很多大虾写了PHP上传类,我综合了一下,写了一个自己喜欢的,提供出来给大家分享。附带了调用代码。

    提醒:
    Form部分要注意,第一记得添加enctype="multipart/form-data",另外input的name=在上传多文件时要定义为数组,即:uploadinput[],如果只上传一个文件可以写为name="uploadinput"。

    因为MSN Spaces中的Blog有字数限制,所以我把代码放在另一个Blog了,大家有兴趣可以点这里http://blog.neten.de/




    11/19/2005

    火星文字

    下面这段代码(也就是某些人形容的火星文字)可以用来生成一个竖直方向可展开的菜单,兼容IE,Firefox,Oprea。写这段小小的代码,我可是走了不少弯路。


    1,关于javascript:

    eval()函数在Firefox中居然不起作用,而且它对onclick()事件也不能很好支持。还好程序员都有共享精神,在网上我找到了一段讲述类似问题的代码,虽然不能直接解决我的问题,但毕竟知道问题出在onclick()和eval()函数上。接下来,调试了半天还是点不动菜单,我几乎要放弃了,后来,凭一点直觉,小改了一下代码,居然成功了。要点一个是event,一个是getElementById,大家可以看代码。

    另外打开页面时加载的javascript函数也要特殊处理,一是调用函数的代码位置要在定义函数的代码位置之后,二是要用window.onload=function(){showsubmenu(0);}的形式调用,如果写window.onload=showsubmenu(0);是会没有反应的。


    2,关于CSS:

    我觉得自己不是一个完美主义者,但为了符合W3C的网页标准,我花了几乎是平时几倍的时间和精力在IE,Firefox,Oprea上调试,看看是不是有相同的显示效果。在CSS的leftnav类中,我开始定义了高度,也就是背景图片的高度。结果点开菜单的时候,在IE正常,在Firefox中展开的部分居然和下面的内容重合。后来在一个不起眼的网页上发现了这个heigh的定义是要不得的。此外我还添加了overflow:hidden;这样改动过后,在所有浏览器都OK了。


    程序员也许就是这样在痛苦中长大的吧。


    下面是代码,作为菜单的背景图片可以下载后放在images目录下。


    图片名称:menuup.gif


    图片名称:menudown.gif



    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html><head><title>菜单</title>
    <META http-equiv=Content-Type content="text/html; charset=utf-8">
    <META content="ZhangPeng" name="author">
    <script language="javascript">
    function showsubmenu(sid,evt){
        evt = evt ? evt : (window.event ? window.event : null);
        if (document.getElementById("submenu" + sid).style.display == "none"){
            document.getElementById("submenu" + sid).style.display = "block";
            document.getElementById("imgmenu" + sid).style.background= 'url(images/menuup.gif)';
        }else{
            document.getElementById("submenu" + sid).style.display = "none";
            document.getElementById("imgmenu" + sid).style.background= 'url(images/menudown.gif)';
        }
    }
    </script>
    <style type="text/css">
    UL.leftnav{
        margin:5px auto 0px;
        font: 14px verdana,geneva,arial,helvetica,sans-serif;
        width: 170px;
        PADDING: 5px 0px 0px 0px ;
        background: url("images/menudown.gif");
        text-align: left;
        LIST-STYLE-TYPE:none;
        cursor: hand;
        overflow:hidden;
        }
    A.navalpha {
        MARGIN:     0px;
        DISPLAY:     block;
        BORDER:     0px;
        BACKGROUND-COLOR:#d6dff7;
        PADDING: 5px 0px 3px 10px ;
        COLOR:         #000;
        FONT-WEIGHT:     normal;
        TEXT-ALIGN:     left;
        TEXT-DECORATION:none;
        WIDTH:         100%;
        font: 12px verdana,geneva,arial,helvetica,sans-serif;
    }
    A.navalpha:visited {
        BACKGROUND-COLOR: #d6dff7;
    }
    A.navalpha:hover {
        BACKGROUND-COLOR:    #E4E4E4;
        color: #EC870E;
        font: 12px verdana,geneva,arial,helvetica,sans-serif;
    }
    </style>
    </head>
    <body>
    <div>
        <span id="imgmenu0"></span>
        <span id="submenu0"></span>
        <UL id="imgmenu1" class="leftnav" onclick="showsubmenu(1,event)" ><span style="padding-left:8px" >修改注册信息</span>
            <div id="submenu1" style="display: block;">
                <li><a class="navalpha" href="#">基本信息</a></li>
                <li><a class="navalpha" href="#">安全信息</a></li>
                <li><a class="navalpha" href="#">附加信息</a></li>
            </div>
        </ul>

        <ul id="imgmenu2" class="leftnav" onclick="javascript:showsubmenu(2,event)"><span style="padding-left: 8px;">帖子管理</span>
            <div id="submenu2" style="display: none;">
                <li><a class="navalpha" href="#">需求信息</a></li>
                <li><a class="navalpha" href="#">供应信息</a></li>
            </div>
        </ul>
        <script>window.onload=function(){showsubmenu(0);}</script>
    </div>
    </body></html>
    10/1/2005

    防止网页在刷新时重复提交

    做法是这样的,首先在SESSION会话中定义一个变量refresh,使它在每次加载网页时自增1.

    1. <?php
    2. if(!isset($_SESSION['refresh'])){//$_SESSION['refresh'] 用来防止重复提交数据
    3.     $sess->my_session_register("refresh");
    4.     $_SESSION['refresh'] = 1;
    5. } else {
    6.     $_SESSION['refresh']++;
    7. }
    8. ?>

    提交表单时,加入参数$_SESSION[’refresh’]:

    1. <form action="?action=blabla&refresh=".$_SESSION['refresh']."  method=\"post\" name=\"abc\"  />

    在处理表单的函数部分,加入一个条件,如果 $_GET[’refresh’]== $_SESSION[’refresh’] - 1,则继续。

    这样在浏览器地址栏的refresh=后面的值在按刷新按钮的时候是不会变的,而加载一次网页 $_SESSION[’refresh’] 则会加1,在这种条件下,$_GET[’refresh’] 是不会等于 $_SESSION[’refresh’] - 1的,防刷功能成功实现。

    7/17/2005

    PHP 中的 addslashes 函数

    addslashes -- 字符串加入斜线。

    语法: string addslashes(string str);

    内容说明

    本函数使需要让数据库处理的字符串中引号的部份加上斜线,以供数据库查询 (query) 能顺利运作。这些会被改的字符包括单引号 (')、双引号 (")、反斜线 backslash (\) 以及空字符 NUL (the null byte)。
    ================================================================
    以上资料是官方的客套话,其实和没说一样。害得我还得亲自做实验。

    1,表单提交中addslashes的表现。
    首先要看get_magic_quotes_gpc()的值,一般为 1 。这时候从 <TEXTAREA> 提交的内容会自动加上斜线。
    比如输 ' 变成 \', " 变成 \" , \ 变成 \\
    例子:

    <html><head><title>test</title></head>
    <body>
    <FORM action="" method=post>
    <TEXTAREA  name=message rows="18" cols="55" >default text</TEXTAREA>
    <INPUT type=submit value=Submit name=submit></FORM>
    <?php
    echo get_magic_quotes_gpc().

            " A ".$_POST['message'].

            " B ".stripslashes($_POST['message']);
    ?>
    </body></html>

    输入:include('/home/me/myfile');
    输出:1 A include(\'/home/me/myfile\'); B include('/home/me/myfile');
    总结:get_magic_quotes_gpc()等于1的情况下,如果不输入数据库,那你得到的结果是加了斜线的。

     ================================================================

    2,提交输入数据库时addslashes的表现。

    例子:

    <html><head><title>test</title></head>
    <body>
    <FORM action="" method=post>
    <TEXTAREA  name=message rows="18" cols="55" >default text</TEXTAREA>
    <INPUT type=submit value=Submit name=submit></FORM>
    <?php
    require_once('includes/common.php');
    $db->query("INSERT INTO `testtable` ( id , content ) VALUES ('1' , '".$_POST['message']."')");
    $query=$db->query("select * from `testtable` where `id`= 1;");
    $Result=$db->fetch_array($query);
    echo get_magic_quotes_gpc().

            " A ".$_POST['message'].

            " B ".$Result['content'];
    ?>
    </body></html>


    输入:include('/home/me/myfile');
    输出:1 A include(\'/home/me/myfile\'); B include('/home/me/myfile');
    总结:get_magic_quotes_gpc()等于1的情况下,如果输入数据库后,再从数据库直接读取的时候,你不做任何修改就可以得到输入的字符串。
     
    ================================================================

    3, get_magic_quotes_gpc()
    get_magic_quotes_gpc()在服务器是的设置是不能runtime修改的,也就是说,你必须在你的网页代码中预先考虑好不同的情况,不然,当你提交数据的时候,你还不知道服务器给你加了斜线没有。以下两个网上流行的函数可能是大家需要的,个人喜欢第二个:

    function my_addslashes( $message ){
        if(get_magic_quotes_gpc()== 1 ){
            return $message;
        }else{
            if(is_array($message)==true){
                while(list($key,$value)=each($message)){
                    $message[$key]=my_addslashes($value);
                }
                return $message;
            }else{
                return addslashes($message);
            }
        }
    }

    function my_addslashes($data){
     if(!get_magic_quotes_gpc()){
       return is_array($data)?
    array_map('AddSlashes',$data):addslashes($data);
     } else {
      Return $data;
     }
    }

    简单的解释就是,如果get_magic_quotes_gpc()等于 1 (服务器默认设置为 1 ),那我们的字符串是可以直接入库的,不修改。不然,我们才用addslashes函数。
    ================================================================

    大家没有看错,我写了半天,就是告诉大家,addslashes() 一般是不起作用的。倒是在不连数据库的情况下,要用到stripslashes()函数,也就是把那讨厌的斜线去掉。

    6/23/2005

    多国语言的尴尬

    我正在开发一个多国语言的网站,理所当然的,我首选 utf-8 作编码,但结果让我大跌眼镜:


    在网页中我要用到session,最好的解决方案当然是存在数据库里面。 当我把一大堆代码写好之后,保存为 utf-8 格式,然后运行,出错是少不了的,我一一耐心排除。到了最后,只剩下一个关于 session 的 Fehlermeldung,大喜,胜利就在眼前了,可是我仔细看了代码,在session_start();之前并没有半点输出,但却一直报错:Cannot send session cookie - headers already sent by...


     。。。


    最后,我建了一个空文件,只写入session_start();一个函数,保存为utf-8 格式,报错相同。保存为ANSI 格式,正常。

    我百度,哈!和我一样的人还真不少,但没有解决方案。原来,编辑器在utf-8文档前加了一点点信息,方便打开时区分格式。这一点点信息恰巧就加在<?php 的前面,造成了输出。


     ,,,千千静听传来了刘欢的《从头再来》。。。


    我只好把代码重新转换,欣喜的是,对欧洲来说,iso-8859-1 也是个不错的选择。


    看来我对完美的追求在某种程度上是一厢情愿的。但谁又能阻止我呢?

    ========================

    6月25号新发现

    ========================

    Emeditor 很不错,可以把utf-8前面的那个BOM输出信息去掉,我又可以回来用utf-8国际编码了,这样省去很多转换乱码的环节。这个世界真美好啊。。

    5/9/2005

    实现更方便的日志编辑

    编辑Blog的时候,可以通过下面的代码,实现更多的编辑选项。

    用法是将红色代码拷贝到网页浏览器的地址栏,然后回车。简单吧。

    javascript:if%20(navigator.userAgent.indexOf("MSIE")>0%20&&%20document.all.rtebox!=null)%20{EditBox.setToolbar("tbmode",true);EditBox.setToolbar("tbfontstyle",true);EditBox.setToolbar("tbfontsize",true);EditBox.setToolbar("tbcut",true);EditBox.setToolbar("tbcopy",true);EditBox.setToolbar("tbpaste",true);EditBox.setToolbar("tbbar1",true);EditBox.setToolbar("tbbar2",true);void(document.all.rtebox.style.height="400");void(document.all.EditBox.style.height="400")}

    另一种方法是loadmemory提供用网站:http://www.siteexperts.com/blogging/editit.htm,网页上有详细的说明。大家一看就明白了。。。