open_basedir可将用户访问文件的活动范围限制在指定的区域,通常是其家目录的路径,也可用符号"."来代表当前目录。注意用open_basedir指定的限制实际上是前缀,而不是目录名。
举例来说: 若"open_basedir = /dir/user", 那么目录 "/dir/user" 和 "/dir/other"都是可以访问的。所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。
open_basedir也可以同时设置多个目录,在Windows中用分号分隔目录,在任何其它系统中用冒号分隔目录。当其作用于Apache模块时,父目录中的open_basedir路径自动被继承。

Apache+PHP配置方法有三种:
方法一:在php.ini里配置
open_basedir = .:/tmp/

方法二:在Apache配置的VirtualHost里设置(httpd-vhosts.conf)
php_admin_value open_basedir .:/tmp/

方法三:在Apache配置的Direcotry里设置
php_admin_value open_basedir .:/tmp/

关于三个配置方法的解释:
a、方法二的优先级高于方法一,也就是说方法二会覆盖方法一;方法三的优先级高于方法二,也就是说方法三会覆盖方法二;
b、配置目录里加了“/tmp/”是因为php默认的临时文件(如上传的文件、session等)会放在该目录,所以一般需要添加该目录,否则部分功能将无法使用;
c、配置目录里加了“.”是指运行php文件的当前目录,这样做可以避免每个站点一个一个设置;
d、如果站点还使用了站点目录外的文件,需要单独在对应VirtualHost设置该目录;

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这里是我实验的一个例子,设置了两个host,当然一块把Apache设置vitualHost的方法也列出了:

#虚拟主机配置文件

NameVirtualHost *:80

#简单设置模式

ServerAdmin admin@8100.cc
DocumentRoot "C:/AWEB/phproot/test"
ServerName localhost
#ServerAlias www.test.com
ErrorLog "logs/error.log"
CustomLog "logs/access.log" common

#详细设置模式

ServerAdmin admin@cc.cc
DocumentRoot "C:/AWEB/phproot/test2"
ServerName www.test2.com
# php_admin_value open_basedir C:/AWEB/phproot/test2/;C:/windows/temp/ 放在这里也可以

Options Indexes FollowSymLinks
AllowOverride Options FileInfo
Order allow,deny
Allow from all
DirectoryIndex index.htm index.html index.php
php_admin_value open_basedir c:/AWEB/phproot/test2/;C:/windows/temp/

Alias /phpmyadmin "C:/AWEB/phpMyAdmin/"

AllowOverride AuthConfig
Order allow,deny
Allow from all

ErrorLog "logs/error.log"
CustomLog "logs/access.log" common

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
最后转军神的那两句话:

一、open_basedir中处理文件路径时没有严格考虑目录的存在,这将导致本地包含或者本地文件读取的绕过(合并/aaa/../../导致linux的目录检查作废)。

二、open_basedir的值配置不当,有可能导致目录跨越(配置时忘记目录最后的斜杠 / )。

分类: 网页设计 标签: 日期:2012-04-26

一、编程之前的分析 

要做一个留言板,而且我们也决定了采用数据库方式做,所以我们要从以下几个步骤开始做: 

1.填写留言 

在什么地方写留言? 

2.传送留言 

在文本框中输入了数据后肯定要以什么方式传到一个什么文件,而后一个文件又是这么接收变量的。 

3.入数据库 

后一个文件将接收的数据要进入数据库,所以,我们还要掌握这么往数据库中写入数据。 

4.查看结果 

将留言写入数据库后,主要是为了能在浏览器中查看,所以,我们要知道这么从数据库中读出数据。 

二、做一个填写留言的文件(write.htm) 

<form action="write_ok.php" method="post">

请输入您的昵称:<input type="text" name="nickname"><br>

请留言:<textarea name="note"></textarea><br>

<input type="submit" value="确定">

</form>
三、PHP变量传送 

熟悉ASP的朋友可能知道,从一个文件传送变量到另一个文件后,第二个文件是request接收数据的;
而PHP似乎更简单,当一个文件将变量传送到另一个文件后,自动产生一个变量,
下面,我将ASP和PHP分别举个例子。 

1.ASP: 

form.htm: 

form action="asp_to.asp" method="post"> 

输入昵称:< input type="text" name="nickname"> 

<input type="submit" value="确定">

</form>

asp_to.asp

您输入的昵称是:<% response.write(request.form("nickname")) %>

简单说明:在第一个文件中,有一个文本框,其名为nickname 和一个确定按钮,在文本框中输入信息后,
点“确定”,浏览器将提交到asp_to.asp 该文件将你在文本框中的内容显示出来,response.write就是显
示输出,而request就是接收变量“nickname”。 

2.PHP: 

form.htm: 

该文件和上面的相同,只是将asp_to.asp改为php_to.php,也就是将输入的变量提交到一个名为php_to.php
的PHP文件。 

php_to.php: 

您输入的昵称是:<? echo $nickname; ?> 

如此而已,其中echo为显示输出,相当于ASP中的 response.write 而$表示变量,PHP的变量用$表示。

四、PHP操作数据库 

在上一节中,我介绍了MySQL数据库和数据表的建立。下面,将从一个例子简单介绍PHP操作数据库的方式。

[ 例一 ]

<?

$id=mysql_connect('localhost','root','adminpassword'); 

$db=mysql_select_db('gsbook',$id); 

$result=mysql_query('select * from gsbook',$db); 

$maxrows=mysql_num_rows($result); 

for ($i=0;$i<$maxrows;$i++) { 

$nickname[$i]=mysql_result($result,$i,'nickname'); 

for ($i=$i-1;$>=0;$i--) 

echo "nickname:".$nickname[$i]."<br>"; 

 

?> 简单说明: 

1.函数 int mysql_connect(string [ hostname ][:port],string [username],string [password])
返回一个MySql的连接ID,其参数相信大家一看就知道。 

2.函数 int mysql_select_db(string database_name, int [ link_identifier ])用来打开数据库,
第一个函数为数据库名称,第二个为MySQL的连接ID,返回值为ture或false 

3.函数 int mysql_query(string query, int [ link_identifier])返回一个结果(result) 

4.函数 int mysql_num_rows(int result)返回query的行数。 

5.函数 int mysql_result(int result,int row,mixed field)该函数返回某字段在某行的结果,
第二个参数为行数,第三个参数为字段名;需要说明的是,该字段名并不是物理字段名,
比如: select field1 as alias_field from table1 那么,在该函数中的第三个参数必须为
 alias_field 而不是 field1。 

6.PHP中的循环语句: 

(1)do ... while 

(2)while ... [end while] 

(3)for (expr1;expr2;expr3)

和C差不多的,在这里不再详细介绍。 

7.在上例中,用了两个for循环语句,第一个用来将数据库中的值读到一个数组中,第二个用来将数组中
的值显示出来。注意第二个for循环的“$i=$i-1;”这是因为在第一个循环后变量$i的值已经自加了1;
所以从数组中取值时,应该减去1。 

8.PHP中字符串的相加用“.”,相当于ASP中(VB语法)的“+”或“&”。 

9.所以,上面代码实现的功能就是从数据库中读出数据,并显示出来。 

下面,我们来向数据库中添加一条记录,先看代码[ 例二 ]:

<?

$id=mysql_connect('localhost','root','adminpassword');

$db=mysql_select_db('gsbook',$id); 

$sql='insert into gsbook values('.chr(39).$nickname.chr(39).')'; 

if (mysql_query($sql,$db)>0) 

echo "OK"; 

}

else

echo "Failed!"; 

}

?>

简单说明: 1.对于熟悉SQL语句的朋友,看了例一的简单介绍后一定知道例二的功能。

分类: 网页设计 标签:, 日期:2012-04-17

十天学会php之第一天

  以 Apache web server 和 MY SQL 作为WEB服务器和数据库在php-4.3.3下的环境做程序简单的构建和访问查看数据库用 PHPMYADMIN。

  PHP的语法:

  1、嵌入方法:

  PHP可以是以<?php或者是<?为开始符号,结束符号是?>,当然也可以自己指定。

  2、引用文件:

  引用文件的方法有两种:require 及 include。

  require 的使用方法如 require("MyRequireFile.php"); 。这个函数通常放在 PHP 程序的最前面,PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部份。常用的函数,亦可以这个方法将它引入网页中。

  include 使用方法如 include("MyIncludeFile.php"); 。这个函数一般是放在流程控制的处理部分中。PHP 程序网页在读到 include 的文件时,才将它读进来。这种方式,可以把程序执行时的流程简单化。

  3、注释方法:

<?php
echo "这是第一种例子。\n" ; // 本例是 C++ 语法的注释
/* 本例采用多行的
注释方式 */
echo "这是第二种例子。\n" ;
echo "这是第三种例子。\n" ; # 本例使用 UNIX Shell 语法注释
?>

  4、变量类型:

$mystring = "我是字符串" ;
$NewLine = "换行了\n" ;
$int1 = 38 ;
$float1 = 1.732 ;
$float2 = 1.4E+2 ;
$MyArray1 = array( "子" , "丑" , "寅" , "卯" );

这里引出两个问题:第一PHP变量以"$"开头,第二PHP语句以";"结尾。这两个遗漏也是程序上大多错误所在。

  5、运算符号:

数学运算:

符号    意义 
+      加法运算 
-       减法运算 
*       乘法运算 
/       除法运算 
%    取余数 
++   累加 
--     递减 

  字符串运算:

  运算符号只有一个,就是英文的句号"."。它可以将字符串连接起来,变成合并的新字符串。

<?
$a = "PHP 4" ;
$b = "功能强大" ;
echo $a.$b;
?>

  这里也引出两个问题,首先PHP中输出语句是echo,第二类似ASP中的<%=变量%>,PHP中也可以<?=变量?>。

逻辑运算:
符号 意义 
<       小于 
>       大于 
<=  小于或等于 
>=  大于或等于 
==     等于 
!=     不等于 
&&    而且 (And) 
and   而且 (And) 
||        或者 (Or) 
or      或者 (Or) 
xor    异或 (Xor) 
!          不 (Not) 

今天就说到这里,明天说一下流程控制。

十天学会php之第二天
学习目的:掌握php的流程控制

1、if..else 循环有三种结构

第一种是只有用到 if 条件,当作单纯的判断。解释成 "若发生了某事则怎样处理"。语法如下:

if (expr) { statement }

其中的 expr 为判断的条件,通常都是用逻辑运算符号当判断的条件。而 statement 为符合条件的执行部分程序,若程序只有一行,可以省略大括号 {}。

范例:本例省略大括号。

<?php
if ($state==1)echo "哈哈" ;
?>

这里特别注意的是,判断是否相等是==而不是=,ASP程序员可能常犯这个错误,= 是赋值。

范例:本例的执行部分有三行,不可省略大括号。

<?php
if ($state==1) {
echo "哈哈 ;
echo "<br>" ;
}
?>
第两种是除了 if 之外,加上了 else 的条件,可解释成 "若发生了某事则怎样处理,否则该如何解决"。语法如下

if (expr) { statement1 } else { statement2 } 范例:上面的例子来修改成更完整的处理。其中的 else 由于只有一行执行的指令,因此不用加上大括号。

<?php
if ($state==1) {
echo "哈哈" ;
echo "<br>";
}
else{
echo "呵呵";
echo "<br>";
}
?>
第三种就是递归的 if..else 循环,通常用在多种决策判断时。它将数个 if..else 拿来合并运用处理。

直接看下面的例子

<?php
if ( $a > $b ) {
echo "a 比 b 大" ;
} elseif ( $a == $b ) {
echo "a 等于 b" ;
} else {
echo "a 比 b 小" ;
}
?>

上例只用二层的 if..else 循环,用来比较 a 和 b 两个变量。实际要使用这种递归 if..else 循环时,请小心使用,因为太多层的循环容易使设计的逻辑出问题,或者少打了大括号等,都会造成程序出现莫名其妙的问题。

2、 for 循环就单纯只有一种,没有变化,它的语法如下

for (expr1; expr2; expr3) { statement }

其中的 expr1 为条件的初始值。expr2 为判断的条件,通常都是用逻辑运算符号 (logical operators) 当判断的条件。expr3 为执行 statement 后要执行的部份,用来改变条件,供下次的循环判断,如加一..等等。而 statement 为符合条件的执行部分程序,若程序只有一行,可以省略大括号 {}。

下例是用 for 循环写的的例子。

<?php
for ( $i = 1 ; $i <= 10 ; $i ++) {
echo "这是第".$i."次循环<br>" ;
}
?>

3、 switch 循环,通常处理复合式的条件判断,每个子条件,都是 case 指令部分。在实作上若使用许多类似的 if 指令,可以将它综合成 switch 循环。

语法如下

switch (expr) { case expr1: statement1; break; case expr2: statement2; break; default: statementN; break; }

其中的 expr 条件,通常为变量名称。而 case 后的 exprN,通常表示变量值。冒号后则为符合该条件要执行的部分。注意要用 break 跳离循环。

<?php
switch ( date ( "D" )) {
case "Mon" :
echo "今天星期一" ;
break;
case "Tue" :
echo "今天星期二" ;
break;
case "Wed" :
echo "今天星期三" ;
break;
case "Thu" :
echo "今天星期四" ;
break;
case "Fri" :
echo "今天星期五" ;
break;
default:
echo "今天放假" ;
break;
}
?>

这里需要注意的是break;别遗漏了,default,省略是可以的。
很明显的,上述的例子用 if 循环就很麻烦了。当然在设计时,要将出现机率最大的条件放在最前面,最少出现的条件放在最后面,可以增加程序的执行效率。上例由于每天出现的机率相同,所以不用注意条件的顺序。

今天就说到这里,明天开始说数据库的使用。

十天学会php之第三天
学习目的:学会构建数据库

在PHP中,MY SQL的命令行编辑可能会令初学者感到很麻烦,不要紧,你下载一个PHPMYADMIN安装一下,以后建立编辑数据库可以靠它了。

下面说一下它的使用。
进入了phpmyadmin后,我们首先需要建立一个数据库,
Language (*) 这里选择中文简体,然后在左边的 创建一个新的数据库 这里填写数据库名字,点击创建即可。

然后在左边下拉菜单中选择那个已经创建的数据库。在下面的

在数据库 shop 中创建一个新表 :
名字 :
字段数 :

中填写表名字和大致你认为的字段数(不够或者多了都不要紧,以后可以再添加或者缺省),按执行。
然后就可以开始建立表了。
第一栏是字段的名字;第二栏选择字段类型:
我们常用的是以下几个:
1)VARCHAR,文本类型
2)INT,整数类型
3)FLOAT,浮点数类型
4)DATE,日期型
5)大家或许会问,自动添加的ID在哪里?这个只要选择INT类型,在后面的额外中选择 auto_increment 就可以了。

建立了表以后,可以在左边看到你建立的表,点击以后,你可以:
1)按右边的结构:查看修改表结构
2)按右边的浏览:查看表中的数据
3)按右边的SQL:运行SQL语句
4)按右边的插入:插入一行记录
5)按右边的清空:删除表中所有记录
6)按右边的删除:删除表

还有一个很重要的功能就是导入和导出,当我们本机做好了程序和数据库的时候,需要在服务器上也有一个本地镜像,如果是ASP的ACCESS简单了,直接上传MDB文件即可,如果是SQL SERVER也可以连接远端服务器进行导入。那么MY SQL中你可以导出所有的SQL语句,到了远端服务器的PHPMYADMIN上,创建数据库后按SQL,粘帖你刚才复制下来的所有本级生成的SQL语句即可。

今天就说到这里,明天继续说数据库操作。
十天学会php之第四天
学习目的:学会连接数据库

PHP简直就是一个函数库,丰富的函数使PHP的某些地方相当简单。建议大家down一本PHP的函数手册,总用的到。

我这里就简单说一下连接MYSQL数据库。

1、mysql_connect

打开 MySQL 服务器连接。
语法: int mysql_connect(string [hostname] [:port], string [username], string [password]); 返回值: 整数

本函数建立与 MySQL 服务器的连接。其中所有的参数都可省略。当使用本函数却不加任何参数时,参数 hostname 的默认值为 localhost、参数 username 的默认值为 PHP 执行行程的拥有者、参数 password 则为空字符串 (即没有密码)。而参数 hostname 后面可以加冒号与端口号,代表使用哪个端口与 MySQL 连接。当然在使用数据库时,早点使用 mysql_close() 将连接关掉可以节省资源。

2、 mysql_select_db

选择一个数据库。
语法: int mysql_select_db(string database_name, int [link_identifier]); 返回值: 整数

本函数选择 MySQL 服务器中的数据库以供之后的资料查询作业 (query) 处理。成功返回 true,失败则返回 false。

最简单的例子就是:
$conn=mysql_connect ("127.0.0.1", "", "");
mysql_select_db("shop");
连接机MY SQL数据库,打开SHOP数据库。在实际应用中应当加强点错误判断。

今天就说到这里,明天再说一下数据库的读取。

十天学会php之第五天
学习目的:学会读取数据

先看两个函数:
1、mysql_query
送出一个 query 字符串。 语法: int mysql_query(string query, int [link_identifier]); 返回值: 整数

本函数送出 query 字符串供 MySQL 做相关的处理或者执行。若没有指定 link_identifier 参数,则程序会自动寻找最近打开的 ID。当 query 查询字符串是 UPDATE、INSERT 及 DELETE 时,返回的可能是 true 或者 false;查询的字符串是 SELECT 则返回新的 ID 值,当返回 false 时,并不是执行成功但无返回值,而是查询的字符串有错误。

2、mysql_fetch_object 返回类资料。 语法: object mysql_fetch_object(int result, int [result_typ]); 返回值: 类

本函数用来将查询结果 result 拆到类变量中。若 result 没有资料,则返回 false 值。

看一个简单的例子:
<?
$exec="select * from user";
$result=mysql_query($exec);
while($rs=mysql_fetch_object($result))
{
echo "username:".$rs->username."<br>";
}
?>
当然,表user中有一个username的字段,这就类似asp中的
<%
exec="select * from user"
set rs=server.createobject("adodb.recordset")
rs.open exec,conn,1,1
do while not rs.eof
response.write "username:"&rs("username")&"<br>"
rs.movenext
loop
%>
当然先要连接数据库,一般我们 require_once('conn.php');而conn.php里面就是上一次说的连接数据库的代码。

小小的两条命令可以完成读取数据的工作了,今天说到这里下一次说数据的添加删除修改。

十天学会php之第六天
学习目的:学会添加删除修改数据

mysql_query($exec);
单这个语句就可以执行所有的操作了,不同的就是$exec这个sql语句

添加:$exec="insert into tablename (item1,item2) values ('".$_POST['item1']."',".$_POST['item1'].")";

删除:$exec="delete from tablename where...";

修改:$exec="update tablename set item1='".$_POST['item1']."' where ...";

说到这里就要说一下表单和php变量传递,如果表单中的一个 <input name="item1" type="text" id="item1">
表单以POST提交的,那么处理表单文件就可以用$_POST['item1']得到变量值,同样以GET提交的就是$_GET['item1']

是不是很简单?但是通常$exec会有问题,因为可能您的SQL语句会很长,您会遗漏.连接符,或者'来包围字符型字段。
我们可以注释mysql_query($exec);语句用echo $exec;代替来输出$exec以检查正确性。如果您还不能察觉$exec有什么错误的话,可以复制这个sql语句到phpmyadmin中执行,看看它的出错信息。还有需要注意的是,我们不要使用一些敏感的字符串作为字段名字,否则很可能会出现问题,比如说date什么的。变量的命名,字段的命名遵循一点规律有的时候对自己是一种好处,初学者并不可忽视其重要性。

今天就说到这里,大家可以DOWN一个SQL语句的参考手册,再研究研究。明天继续说SESSION。

十天学会php之第七天
学习目的:学会SESSION的使用

SESSION的作用很多,最多用的就是站点内页面间变量传递。

在页面开始我们要session_start();开启SESSION;
然后就可以使用SESSION变量了,比如说要赋值就是:$_SESSION['item']="item1";要得到值就是$item1=$_SESSION['item'];,很简单吧。这里我们可能会使用到一些函数,比如说判断是不是某SESSION变量为空,可以这么写:empty($_SESSION['inum'])返回true or false。

下面综合一下前面所说的我们来看一个登陆程序,判断用户名密码是否正确。
登陆表单是这样:login.php
<table width="100%" height="100%" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<form action="checklogin.php" method="post"><td align="center" valign="middle"><table width="400" border="0" cellpadding="5" cellspacing="1">
<tr>
<td colspan="2"><div align="center">Administrators Login</div></td>
</tr>
<tr>
<td><div align="center">Username</div></td>
<td><div align="center">
<input name="username" type="text" id="username">
</div></td>
</tr>
<tr>
<td><div align="center">Password</div></td>
<td><div align="center">
<input name="password" type="password" id="password">
</div></td>
</tr>
<tr>
<td colspan="2"><div align="center">
<input type="submit" name="Submit" value="Submit">
<input type="reset" name="Submit2" value="Clear">
</div></td>
</tr>
</table></td></form>
</tr>
</table>

处理文件是这样
<?
require_once('conn.php');
session_start();
$username=$_POST['username'];
$password=$_POST['password'];
$exec="select * from admin where username='".$username."'";
if($result=mysql_query($exec))
{
  if($rs=mysql_fetch_object($result))
  {
    if($rs->password==$password)
    {
      $_SESSION['adminname']=$username;
      header("location:index.php");
    }
    else
    {
      echo "<script>alert('Password Check Error!');location.href='login.php';</script>";
    }
  }
  else
  {
  echo "<script>alert('Username Check Error!');location.href='login.php';</script>";
  }
  }
else
{
echo "<script>alert('Database Connection Error!');location.href='login.php';</script>";
}

?>

conn.php是这样:
<?
$conn=mysql_connect ("127.0.0.1", "", "");
mysql_select_db("shop");
?>

由于 $_SESSION['adminname']=$username;我们可以这样写验证是否登陆语句的文件:checkadmin.php
<?
session_start();
if($_SESSION['adminname']=='')
{
echo "<script>alert('Please Login First');location.href='login.php';</script>";
}
?>

呵呵,今天说到这里,明天说一下怎么弄一个分页。

十天学会php之第八天
学习目的:做一个分页显示

关键就是用到了SQL语句中的limit来限定显示的记录从几到几。我们需要一个记录当前页的变量$page,还需要总共的记录数$num

对于$page如果没有我们就让它=0,如果有<0就让它也=0,如果超过了总的页数就让他=总的页数。

$execc="select count(*) from tablename ";
$resultc=mysql_query($execc);
$rsc=mysql_fetch_array($resultc);
$num=$rsc[0];

这样可以得到记录总数
ceil($num/10))如果一页10记录的话,这个就是总的页数

所以可以这么写
if(empty($_GET['page']))
{
$page=0;
}
else
{
$page=$_GET['page'];
if($page<0)$page=0;
if($page>=ceil($num/10))$page=ceil($num/10)-1;//因为page是从0开始的,所以要-1
}

这样$exec可以这么写 $exec="select * from tablename limit ".($page*10).",10";
//一页是10记录的

最后我们需要做的就是几个连接:
<a href="xxx.php?page=0">FirstPage</a>
<a href="xxx.php?page=<?=($page-1)?>">PrevPage</a>
<a href="xxx.php?page=<?=($page+1)?>">NextPage</a>
<a href="xxx.php?page=<?=ceil($num/10)-1?>">LastPage</a>

这是一个大致的思路,大家可以想想怎么来优化?今天说到这里,明天说一下一些注意的问题。

十天学会php之第九天

学习目的:注意事项

1、注意不要漏了分号
2、注意不要漏了变量前的$
3、使用SESSION的时候注意不要遗漏session_start();

  如果发生错误的时候,可以采用以下方法:
1、如果是SQL语句出错,就注释了然后输出SQL语句,注意也要注释调后续的执行SQL语句
2、如果是变量为空,大多是没有传递到位,输出变量检查一下,检查一下表单的id和name
3、如果是数据库连接出错,检查是否正确打开MY SQL和是否遗漏了连接语句
4、注意缩进,排除括号不区配的错误

  在做大网站的时候,我的思路是先构建数据库,确定每一个字段的作用,和表之间的关系。然后设计后台界面,从添加数据开始做起,因为添加是否成功可以直接到数据库里面验证,做好了添加再做显示的页面,最后才是两者的结合。一般来说后台就包括添加删除修改和显示,后台没有问题了,前台也没有什么大问题。前台还需要注意安全性和容错还有就是输出格式。

  好了,今天说到这里,明天说一下如果用PHP上传文件和发邮件。

十天学会php之第十天
  学习目的:学会用PHP上传文件和发邮件

  上传文件表单必须加上 enctype="multipart/form-data" 和 <input type="file" name="file">下面看一下代码:

$f=&$HTTP_POST_FILES['file'];
$dest_dir='uploads';//设定上传目录
$dest=$dest_dir.'/'.date("ymd")."_".$f['name'];//我这里设置文件名为日期加上文件名避免重复
$r=move_uploaded_file($f['tmp_name'],$dest);
chmod($dest, 0755);//设定上传的文件的属性

  上传的文件名为date("ymd")."_".$f['name'] ,可以在以后插入到数据库的时候用到,PHP实际上是把你上传的文件从临时目录移动到指定目录。move_uploaded_file($f['tmp_name'],$dest);这是关键

  至于发邮件就更加简单,可以使用mail()函数mail("收件人地址","主题","正文","From:发件人\r\nReply-to:发件人的地址");

  不过mail()需要服务器的支持,在WINDOWS下还需要配置SMTP服务器,一般来说外面的LINUX空间都行。

  好像上传文件和发邮件比ASP简单很多,只要调用函数就可以了。ASP还需要用到服务器的不同组件比如FSO、JMAIL什么的。

  十天学会PHP说到这里了,想告诉大家的是PHP入门可以是十天,但是精通决不是十天啊,还需要大家自己去研究。

分类: 网页设计 标签: 日期:2012-04-17

1、/ckeditor/config.js, 配置文件,如果不想写太多,可以直接写好默认配置(语言,菜单栏,宽度),有需要可以百度config配置
config.language = ‘en’;config.skin = ‘v2’;config.uiColor = ‘#AADC6E’;config.toolbar = ‘Basic’;…。

2、官方的demo大多都喜欢用js配置editor区域,习惯写php的我就嫌麻烦,只好看内置的php类。

require_once ROOTPATH 。 “ckeditor/ckeditor.php”;$CKEditor = new CKEditor();$CKEditor-》returnOutput = true; //设置输出可用变量的情况$CKEditor-》basePath = ‘/ckeditor/’;//设置路径$contentarea = $CKEditor-》editor(“content”, $rs[‘contents’]); //生成一个以name为content的textarea

echo $contentarea;

3、需要上传了 ,只好加入ckfinder.把ckfinder和ckeditor放在同级目录下。

打开/ckfinder/config.php, 首先设置第一个函数CheckAuthentication(),这个函数需要按照自己的规则写,只要return true的情况才能允许上传文件到服务器的,当然不建议直接写return true,这将导致安全问题。可以采用session来处理比较方便。

session_start();function CheckAuthentication(){ if(isset($_SESSION[‘UseEidtor’]))

return true;else return false;}

4、上传文件位置:也在/ckfinder/config.php, 找到$baseUrl,之前一直想自己写一个方法用来定位路径,实在不好办,后来只好用sesssion,如果一个网站中,有需要上传到不同的位置,正好可以利用session定位。

if (isset($_SESSION[‘UseEidtor’])) {

switch ($_SESSION[‘UseEidtor’]) { case ‘Addr1’:$baseUrl = ‘/addr1/uploadfile/’;case ‘Addr2’:$baseUrl = ‘/addr2/upfiles/’;}

} else {

$baseUrl = ‘/upfiles/’;

} 5、对于上传文件名,ckfinder会按照原有的名字命名,中文的情况下可能会乱码,所以建议使用日期重命名。打开/ckfinder/core/connector/php/php5/CommandHandler/FileUpload.php 找到《 /p》

$sUnsafeFileName =CKFinder_Connector_Utils_FileSystem::convertToFilesystemEncoding(CKFinder_Connector_Utils_Misc::mbBasename($uploadedFile[‘name’]));后面加上

$sExtension = CKFinder_Connector_Utils_FileSystem::getExtension($sUnsafeFileName);$sUnsafeFileName=date(‘YmdHis’)。‘。’.$sExtension;6、 最后就是使用ckfinder

require_once ROOTPATH 。 “ckeditor/ckeditor.php”;require_once ROOTPATH 。 ‘ckfinder/ckfinder.php’ ;

$CKEditor = new CKEditor();$CKEditor-》returnOutput = true;$CKEditor-》basePath = ‘/ckeditor/’;

CKFinder::SetupCKEditor($CKEditor, ‘/ckfinder/’) ;//注意这里是相对路径,相对于根目录,不能用绝对路径

$contentarea = $CKEditor-》editor(“content”, $rs[‘contents’]);两者配合用起来还是挺不错的,更重要的原因是安全性高了很多。

分类: 网页设计 标签:, , 日期:2012-04-16

<?php   foreach(array(     'rsd_link',//rel="EditURI"     'index_rel_link',//rel="index"     'start_post_rel_link',//rel="start"     'wlwmanifest_link'//rel="wlwmanifest"   ) as $xx)   remove_action('wp_head',$xx);//X掉以上   function the_category_filter($thelist){//rel="category"或rel="category tag", 这个最巨量     return preg_replace('/rel=".*?"/','rel="tag"',$thelist);   }   add_filter('the_category','the_category_filter'); ?>

将以上代码加到functions.php里面去,Wordpress就不会生成烦人无用的rel属性了

分类: 网页设计 标签:, 日期:2011-06-05

Deprecated: Function ereg_replace() is deprecated in

    由于PHP版本是5.3.3。

    查询了一下,这个错误的意思是说:config.php文件里ereg_replace()不能执行或执行错了。

    而出现这个问题的原因是PHP的版本问题:DEDE的开发人员现在还在5.1时代,不知道ereg_replace是php5.3中废弃的标签,不推进使用了。PHP5.3及以上一些函数已经淘汰了,不被支持。而DEDE很多都是使用的5.2以前的函数写的。官方也没有做这方面的更新。
   自己整理了一下,找到了下面的几种解决方法:
   1.从新下一个个PHP5.2,安装后,将版本切换到5.2,问题解决了。
   2.信息提示是不推荐使用ereg_replace(),你加个@看能不能屏蔽掉,@ereg_replace(...)
   3.要是不行的话,就改改吧,将dede\config.php文件的第二行替换成
 define(’DEDEADMIN’, preg_replace(”/[\/\\\\]{1,}/”, ‘/’, dirname(__FILE__) ) );

   4.要是加那一句不行的话,就改成下面的样子吧:
(1)define('DEDEADMIN', preg_replace("/[\/\\\\]{1,}/", '/', dirname(__FILE__) ) );
(2)define('DEDEADMIN',strtr(dirname(__FILE__),'\\/','//'));

分类: 网页设计 标签: 日期:2011-06-03

使用WordPress搭建的博客,安装此插件后,可以在文章或页面中分享作者喜爱的歌曲。

该插件提供搜索功能,作者输入关键字,即可搜索出希望分享的歌曲。分享后页面中自动出现亦歌迷你播放器,播放分享的歌曲。

在管理平台的“插件”->“添加新插件”中,搜索“1g music share”,即可找到此插件,轻松安装。

安装WordPress分享插件

分类: 网页设计 标签: 日期:2011-06-01

107 个机器人
Yahoo Slurp
Unknown robot (identified by 'crawl')
Googlebot
Yahoo! Slurp China
GouGou
OutfoxBot
GigaBot
Lilina
MSNBot
Java (Often spam bot)
NewsGator Online
BaiDuSpider
Sina Iask Spider
Bloglines
MagpieRSS
Alexa (IA Archiver)
Feedfetcher-Google
MT::Telegraph::Agent
Feedburner (更多...)

分类: 网页设计 标签: 日期:2011-02-23

email输入类型

<INPUT type=email name=email>
 
此类型要求输入格式正确的email地址,否则浏览器是不允许提交的,并会有一个错误信息提示.此类型必须指定name值,否则无效果.

url输入类型

<INPUT type=url>
 
上面代码展示的文本域要求输入格式正确的URL地址,Opera中会自动在开始处添加http://.

日期时间相关输入类型(这些个很牛X的)

<INPUT type=date>
<INPUT type=time>
<INPUT type=month>
<INPUT type=week>
 
这一系列是很酷的一个类型,完全解决了烦琐的JS日历控件问题.但目前MS只有Opera/Chrome新版本支持,且展示效果也不一样.

number输入类型(这些个很牛X的)

<INPUT type=number>
 
这个不用多解释了,要求输入一个数字字符,若未输入则会抛出一个错误.

range输入类型

<INPUT type=range>
 
此类型将显示一个可拖动的滑块条,并可通过设定max/min/step值限定拖动范围.拖动时会反馈给value一个值.

search输入类型

<INPUT type=search>
 
此类型表示输入的将是一个搜索关键字,通过results=s可显示一个搜索小图标.

tel输入类型

<INPUT type=tel>
 
此类型要求输入一个电话号码,但实际上它并没有特殊的验证,与text类型没什么区别.

color输入类型

<INPUT type=color>
 
此类型表单,可让用户通过颜色选择器选择一个颜色值,并反馈到value中.

三、新增的表单属性

placeholder属性

<INPUT id=placeholder placeholder="点击我会以清除">
 
这是一个很实用的属性,免去了用JS去实现点击清除表单初始值.浏览器支持也还不错,MS除了Firefox,其他标准浏览器都能很好的支持.

require/pattern属性

<INPUT id=placeholder name=require required>
<INPUT id=placeholder name=require1 required="required">
<INPUT name=require2 pattern="^[1-9]\d{5}$">
 
表单验证属性,require类型时,若输入值为空,则拒绝提交,并会有一个提示。上面两种写法都对,这个很有用。并且可以用于textarea以及hidden/image/submit类型.pattern类型为正则验证,可以完成各种复杂的验证。这两种类型必须指定name值,否则无效果。

autofocus属性

<INPUT autofocus="true">
 
默认聚焦属性,可在页面加载时聚焦到一个表单控件,类似于JS的focus().

list属性

<INPUT id=list list="ilist">
<DATALIST id=ilist>
 <OPTION value="a" label="a">
 <OPTION value="b" label="b">
 <OPTION value="c" label="c">
</DATALIST>
 
该属性需要与datalist属性共用,datalist是对选择框的记忆,而list属性可以为选择框自定义记忆的内容。

max/min/step属性

<INPUT type=range step="20" min="1" max="100">
 
限制值的输入范围,以及值的输入渐进程度,比如可在number设定输入最大值最小值,或者在range中设定拖动阶梯。

autocomplete属性

<INPUT id=autocomplete autocomplete="on">
 
此属性是为表单提供自动完成功能。如果该属性为打开状态可很好地自动完成。一般来说,此属性必须启动浏览器的自动完成功能。

分类: 网页设计 标签: 日期:2011-02-21

一、什么时候应用系统会从缓存中获取数据?

  数据库从服务器上读取数据时,可以从硬盘的数据文件中获取数据,也可以从数据库缓存中读取数据。现在数据库管理员需要搞清楚的是,在什么样的情况下,系统是从缓存中读取数据,而不是从硬盘的数据文件中读取数据?

  简单的说,数据缓存就是内存中的一块存储区域,其存储了用户的SQL文本以及相关的查询结果。通常情况下,用户下次查询时,如果所使用的SQL文本是相同的,并且自从上次查询后,相关的纪录没有被更新过,此时数据库就直接采用缓存中的内容。从这个原则中,可以看到如果要直接使用缓存中的数据,至少要满足以下几个条件。

  一是所采用的SQL文本是相同的。当前后两次用户使用了相同的SQL语句(假设不考虑其他条件),则服务器会从缓存中读取结果,而不需要再去解析和执行SQL语句。这里需要注意的是,这里的SQL文本必须一次不差的完全相同。如果前后两次查询,使用了不同的查询条件。如第一次查询时没有输入Where条件语句。后来发现数据量过多,利用了Where条件了过滤查询的结果。此时即使最后的查询结果是相同的,系统仍然是从数据文件中获取数据,而不是从数据缓存中。再如,Select后面所使用的字段名称也必须是相同的。如果有一个字段名称不同或者前后两次查询所使用的字段数量不同,则系统都会认为是不同的SQL语句,而重新解析并查询。

  二是从数据缓存的角度考虑,大小写是不敏感的。如前后两次查询时,采用的字段名称可能只有大小写的差异。如第一次使用的是大小,第二次使用的是小写,这系统认为仍然是相同的SQL语句。或者说关键字大小写等等这都是不敏感的。

  三是要满足二次查询之间,数据记录包括表结构都没有被更改过。如果记录所在的标更改了,如增加了一个字段等等,此时使用这个表的所有缓冲数据系统将自动清空。这里需要注意,这里指的更改是一个广义的更改,包括表中任何数据或者结果的改变。举一个简单的例子,第一次查询时用户需要查询2010年的出货数据。查询后有用户在这个表中插入了一条2011年1月份的出货信息。然后又有用户需要查询2010年的出货信息。使用的SQL语句与第一次查询时完全相同。在这种情况下,数据库系统会使用缓存中的数据吗?答案是否定的。因为当中间用户插入一条记录时,系统会自动清空跟这个表相关的所有缓存记录。当第二次查询时,缓存中已经没有这张表对应的缓存信息。此时就需要重新解析并查询。

  四是需要注意,默认字符集对缓存命中率的影响。通常情况下,如果客户端与服务器之间所采用的默认字符集不同,则即使查询语句相同、在两次查询之间记录与表结构也没有被更改,系统仍然认为是不同的查询。对于这一点需要特别的注意,大家比较容易忽视。

  二、提高缓存命中率的建议。

  从上面的条件分析中可以看出,利用缓存中的数据具有比较严格的条件。其实这些条件也是合情合理的。主要是为了保障数据的一致性。对以上这些条件有深入的认识之后,现在数据库管理员需要考虑的是,如何来提高这个缓存的命中率?对此笔者有如下几个建议。

  一是在配置时,客户端与服务器端要使用相同的字符集。如果客户端(或者说第三方工具)与服务器端使用的字符集不同,那么任何情况下都不会使用缓存功能。特别在国内,需要用到中文的字符集。此时特别需要注意,客户端默认字符集要与服务器端的默认字符集相同。注意,这里是相同,而不是兼容。有时候即使采用了不同的字符集,客户端上仍然可以正常显示。这主要是因为有些字符集虽然不相同,但是是相互兼容的。在缓存管理上,需要相同,光兼容还不行。

  二是在客户端上,要固化查询的语句。如现在有财务人员和采购人员同时从系统中查询11月份的出货数据。显然他们岗位职责不同,所需要字段的内容是不同的。此时在客户端出,可以允许用户设置自己所需要的表单格式。但是笔者建议,后台所采用的SQL语句最好是相同的。这里数据会经过三个渠道:后台数据库、客户端、用户。笔者的意识时,后台数据库与客户端之间的交互采用相同的SQL语句。然后客户端与用户之间进行交互时,根据用户定义的格式(包括字段前后的排列、不包括查询条件语句的差异)向用户显示数据。此时由于采用了相同的SQL语句(只是用户对于显示格式的要求不同),从而可以提高应用系统的查询效率。

  三是提高内存中缓存的配置,来提高命中率。一般在服务器启动时,操作系统会跟数据库软件协商缓存空间的大小。当缓存工作不足时,缓存中最旧的缓存记录会被最新的消息所覆盖。可见,如果能够提高缓存空间,就可以提高命中率。这就好像打靶,目标多了,命中的几率也会高许多。不过用户的并发数越多,这个设置的效果会越不明显。

  四是通过分区表可以提高缓存的命中率。在上面的条件分析中,大家可以看到,只要所查询的表中插入了一条记录,系统就会清空缓存记录。现在以查询出货记录为例。出货记录表每天都在更新,而用户在年初时,会经常需要查询上一年的出货记录。此时由于这个表中的数据每个小时都在更新,那么缓存中的信息会不断的被情况。此时缓存的命中率显然不会很高。针对这种情况,笔者建议可以采用分区表。如可以通过系统设置,将2010年的出货记录单独存放在一个出货的分区表中。即每一个年度都使用一张单独的分区表。此时2011年的纪录,就不会影响到2010年的分区表。此时如果用户重复查询2010年的出货信息,只要其使用的SQL语句相同(没有采用不同的查询条件),那么就可以享受缓存机制所带来的效益,提高应用系统的查询效果。。

  三、多个应用对缓存的影响。

  通常情况下,MySQL数据库的缓存是根据服务器内存的大小自动分配的。如果一台服务器上只有一个MySQL应用,那么固然最好。不过在实际工作中,为了降低信息化投资的成本,往往会在同一台服务器上布置多个信息化应用。由于其他信息化应用也需要使用内存的空间作为缓存,那么MySQL数据库中缓存空间就可能变小。如果遇到这种情况下,数据库管理员需要跟系统工程师进行协商,为各种不同的应用根据性能要求的不同,手工设置不同的缓存空间。如此的话,就可以避免同一台服务器上不同信息化应用对缓存的冲突。

分类: 网页设计 标签: 日期:2011-02-10