浏览模式: 标准 | 列表2007年01月的文章

路比你想象中要难走

今天我尝试了,用PHP+access写东西。本以为很容易的东西。却被我搞得一塌糊涂。虽然我也有了准备和计划。先是尝试用php+adodb,失败了。于是乎赤膊上阵,开始 $conn=new COM("ADODB.Connection") or die("Conn failed!"); ……,还是没有成功。只好换用asp.net2.0 + ACCESS。可是我真的很愚笨,总是搞得很是难看,对于美化无从下手。现在体会到了,贪多嚼不烂的道理了。
为了多吸收一些东西,淡水河边这厮在不长的时间里,恶补了一下php+mysql,其中又回温了一阵子asp.net。做项目用的是ASP。项目中的小论坛又是用JScript写的。现在好了,想搞个php+access的东西都拖拉了这么长的时间。真是惭愧。想回忆起那些资料上的程式,却总也写不出那些细节。看来还要再去多看看才行啊。明天接着写吧,决定了,php就是他了。再难啃,我也要吃下它[angry]

Tags: php+access

AspJpeg制作透明文字水印

效果图:
点击在新窗口中浏览此图片
技术支持:
   1、aspjpeg能对图片水印进行透明度调整,不能对文字水印调整,
   2、aspjpeg支持Binary,可以Jpeg.OpenBinary读取,可以Jpeg.sendBinary,也可Jpeg.Binary赋值
思路:
   1、把原始的图片数据二进制度赋值给TempA,
   2、将文字水印处理后的图片数据二进制赋值给TempB,
   3、以TempB作为"图片水印",附加在TempA上,调整透明度,输出就ok了

思路很简单,代码也很简单:
<%
LocalFile="d:\apple.jpg"
TargetFile="d:\myapple.jpg"
Dim Jpeg
Set Jpeg = Server.Cr&#101;ateObject("Persits.Jpeg")
If Err.Number=-2147221005 then
Response.write "没有这个组件,请安装!""检查是否安装AspJpeg组件
Response.End()
End If
Jpeg.Open (LocalFile)"打开图片
If err.number then
Response.write"打开图片失败,请检查路径!"
Response.End()
End if
Dim TempA "原始图片的二进制数据
Dim TempB "加了不透明文字水印的图片
Dim TempC "最终效果
TempA=Jpeg.Binary"将原始数据赋给TempA
"=========加文字水印=================
Jpeg.Canvas.Font.Color = &amp;Hfffffff"水印文字颜色
Jpeg.Canvas.Font.Family = Arial"字体
Jpeg.Canvas.Font.Bold = True"是否加粗
Jpeg.Canvas.Font.Size = 35"字体大小
Jpeg.Canvas.Font.ShadowColor = &amp;H000000"阴影色彩
Jpeg.Canvas.Font.ShadowYOffset = 1
Jpeg.Canvas.Font.ShadowXOffset = 1
Jpeg.Canvas.Brush.Solid = True
Jpeg.Canvas.Font.Quality = 5"输出质量
Jpeg.Canvas.PrintText Jpeg.OriginalWidth/2-150,Jpeg.OriginalHeight/2,"www.Tsingfeng.com"...水印位置及文字
TempB=Jpeg.Binary"将文字水印处理后的值赋给TempB,这时,文字水印没有不透明度
"============调整文字透明度================
Set MyJpeg = Server.Cr&#101;ateObject("Persits.Jpeg")
MyJpeg.OpenBinary TempA
Set Logo = Server.Cr&#101;ateObject("Persits.Jpeg")
Logo.OpenBinary TempB
MyJpeg.DrawImage 0,0, Logo, 0.2"0.3是透明度
TempC=MyJpeg.Binary"将最终结果赋值给TempC,这时也可以生成目标图片了
response.BinaryWrite TempC"将二进输出给浏览器
MyJpeg.Save (TargetFile)
set TempA=nothing
set TempB=nothing
set TempC=nothing
Jpeg.close
MyJpeg.Close
Logo.Close
%>
原图:
点击在新窗口中浏览此图片

Tags: aspjpeg, 水印

Aspjpeg入门详解

ASPJPEG是一款功能相当强大的图象处理组件,用它可以轻松地做出图片的缩略图和为图片加上水印功能。呵呵,应该都知道了。先说制作缩略图吧
1、为图片制作缩略图
<%
" ###建立实例###
Dim Jpeg,Path
Set Jpeg = Server.Cr&#101;ateObject("Persits.Jpeg")
" ###图片所在位置###
Path = Server.MapPath("images/clock.jpg")
" ###打开###
Jpeg.Open Path
" ###设置缩略图大小(这里比例设定为原图的50%)###
"###OriginalWidth属性为原图的宽,OriginalHeight为原图的高###
"###也可以直接指定Width和Height 属性为具体数值###
Jpeg.Width = Jpeg.OriginalWidth / 2
Jpeg.Height = Jpeg.OriginalHeight / 2
" ###保存缩略图到指定文件夹下###
Jpeg.Save Server.MapPath("images/clock_small.jpg"")
" ###注销实例###
Set Jpeg = Nothing
%>

2、为图片加入水印功能
   2.1加入文字水印
<%
Dim Jpeg
" 建立实例
Set Jpeg = Server.Cr&#101;ateObject("Persits.Jpeg")
" 打开目标图片
Jpeg.Open Server.MapPath("images/dodge_viper.jpg")
" 添加文字水印
Jpeg.Canvas.Font.Color = &amp;HFF0000" 红色
Jpeg.Canvas.Font.Family = "宋体"
Jpeg.Canvas.Font.Bold = True
Jpeg.Canvas.Print 10, 10, "Copyright (c) TSINGFENG.com"
" 保存文件
Jpeg.Save Server.MapPath("images/dodge_viper_framed.jpg")
" 注销对象
Set Jpeg = Nothing
%>

   2.2加入图片水印
<%
LocalFile="d:\apple.jpg"
LogoFile="d:\logo.jpg"
TargetFile="d:\myapplelogo.jpg"
Set LocalJpeg = Server.Cr&#101;ateObject("Persits.Jpeg")
LocalJpeg.Open (LocalFile) "打开处理图片
Set Logo = Server.Cr&#101;ateObject("Persits.Jpeg")
Logo.Open (LogoFile) "打开水印图片
LocalJpeg.DrawImage 255,280, Logo, 0.5 "0,0是位置,0.5是透明度
TempA=localJpeg.binary
response.BinaryWrite TempA"将二进输出给浏览器
LocalJpeg.Save (TargetFile) "保存加了水印的图片
set TempA=nothing
Logo.close
LocalJpeg.close
%>
以上代码,淡水河边这厮都测试通过了。

Tags: aspjpeg, 水印

才发现PR值2了

无聊之中查了一下PR值。已经不记得上次是什么时候也查过一次,0。
突然发现现在已经变成2了。
我好像也没有怎样用心打理,做的最多的就是不断地换皮了。今天这个skin,明天那个skin。这个应该不会有影响吧。呵呵。
有些事情就是这样奇怪,当你似乎已经快要忘记的时候,它却会回头给你惊讶。
只是这样的事在我身上不多。所以值得庆贺一下。今天太晚了,明天吧。明天早上多吃一个包子[razz]

Tags: google, pr

封装好的PHP+AJAX实现简单分页

这个实例的重点需要灵活运用AJAX,难点在于中文的编码。AJAX+PHP分页的基本原理就是在数据库一定的位置上取一定量的数据,然后利用AJAX进行调用.先看看PHP分页部分:
代码:
<?php
header("Content-type: text/html;charset=GBK");//输出编码,避免中文乱码
$conn = mysql_connect("localhost","root","password") o&#114; die ("Not connected : " . mysql_error());
mysql_sel&#101;ct_db("web", $conn) o&#114; die ("Cannot use foo : " . mysql_error());
//mysql_query("set character set gbk");//可选,解决Mysql中文乱码

$p = $_POST["p"];//获取页面编号

$result_t=mysql_query("sel&#101;ct count(*)  from `tablename`");
$total=mysql_fetch_array($result_t);
$total=$total[0];


$s = 20;//定义每页显示数量
$t = floor($total/$s);//总页数

if(!$p||$p<0){$p = 0;}
if($p>$t){$p = $t;}
$pp = $s*$p;

$query="sel&#101;ct * from `tablename` o&#114;der by `id` desc limit $pp,$s";//取出相应的数据
$result=mysql_query($query);

while ($row = mysql_fetch_array($result, MYSQL_BOTH)) {
echo "<p>".$row["id"]."</p>";
}

echo "共有".$total."条记录<a href="javascript:dopages(".($p-1).")">上一页</a> | <a href="javascript:dopages(".($p+1).")">下一页</a>跳转至<input type="text" id="pgs" />页<input value="跳转" type="button" onClick="dopages("."document.getElementById("pgs").value-1);>";
?>

这样就通过简单的方法实现了分页功能,接下来就需要利用AJAX进行调用了:
代码:
function dopages(p){        
        var posts = "p="+p;
        var url = ajaxurl("pages.php");
        function func(){
            getResult("dopages");
        };
        sendRequest(url,posts,func);
}
function ajaxurl(adDiv){
        var baseurl = "http://ad.nie.netease.com/... + adDiv;
        return baseurl;        
        }
function getajax(){
        var xmlhttp = false;
        if(window.ActiveXObject){
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        else if(window.XMLHttpRequest){
                xmlhttp = new XMLHttpRequest();
        }
        return xmlhttp;
        }
function sendRequest(url,posts,func){
        ajax = getajax();
        ajax.onreadystatechange = func;
        ajax.open("POST", url, true);
        ajax.setRequestHeader("Content-Length",posts.length);
        ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        ajax.send(posts);        
}
/*------------Try-------------*/
var Try = {
  these: function() {
    var returnValue;
    for (var i = 0; i < arguments.length; i++) {
      var lambda = arguments;
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }
    return returnValue;
  }
}

function tryCollectGarbage(){
    return Try.these(
        function() {return CollectGarbage();},
        function() {return false;}
        );
}
function getResult(adDiv,num){
        if (ajax.readyState < 4) {
                document.getElementById("loading").style.visibility = "visible";
        }
        else if (ajax.readyState == 4) {
                document.getElementById("loading").style.visibility = "hidden";
                if (ajax.status == 200){
                var result = ajax.responseText;
                if(adDiv=="dopages"){
                        document.getElementById("xpages").innerHTML = result;
                        }
        }
                else {
                        alert("出错");
                        del&#101;te ajax;
                        tryCollectGarbage();//垃圾回收
                }
        }
}
  

Tags: AJAX

网站接案后得设计流程

适合SOHO,和中小型的设计、广告公司。
点击在新窗口中浏览此图片
上面存在一个关键过程
“需求”阶段,必须和用户进行充分的交流,完全、准确的了解用户的需求。既不能歪曲用户的意思,也不能一味迎合用户的非正当需求,也不能对自己没有把握的技术甚至不可能实现的技术夸下海口。需求分析是一个沟通、交流、引导、教育、斗争、妥协的过程。需求分析结果要有文字资料存档。
  技术参数必须了解准确。比如用户的软件平台是linux系列,那你的系统就只好用PHP+Apache开发了,这时候你的ASP,ASP.NET技术就用不上了。能用静态网页表现的内容,尽量不用程序代码动态实现(方便移植,不管是linux还是windows,对Html都一样了)。在必要的时候,让用户对已经确定的需求内容签字,盖章。

代码简洁的分页函数

function splitpage($pageall,$page=1,$urled=null,$strpage = \"page\",$pageaverage = 10){
    $pageaverage -= 1;
    $page=intval($page >= 1 ?$page:1 );
    $page=$page>$pageall?$pageall:$page;
    $startpage=$page- $pageaverage  >0?$page- ceil(($pageaverage / 2)):1;
    $startpage=($page + ceil($pageaverage /2) >$pageall)?$pageall-$pageaverage:$startpage;
    
    $startpage=$startpage >0?$startpage:1;
    $stoppage= $startpage+$pageaverage >$pageall?$pageall:$startpage+$pageaverage;
    if($urlfile==null) $urlfile=$php_self;
    if(!strrpos($urlfile,\"?\")) $urled  .= \"?\";
    foreach($_GET as $k => $v) {
        $urled = ($k<>$strpage) ?  $urled.$k.\"=\".urlencode($v).\"&amp;\" :  $urled;
    }

    if ($page>1){
        $mess    =\"<a href=\"\".$urled.$strpage.\"=1\">|<</a>\";
        $mess    .=\"<a href=\"\".$urled.$strpage.\"=\".($page-1).\"\"><</a>\";
    }else{
        $mess    =\"|< ?\";
        $mess    .=\"< ?\";
    }
    for($i= $startpage; $i<= $stoppage ;$i++){
        if($i<= $pageall&amp;&amp; !($page==$i))
            $mess    .=    \"<a href=\"\".$urled.$strpage.\"=\".$i.\"\">\".$i.\"</a>?\";
        else
            $mess    .=    \"\".$i.\"?\";
    }
    if ($page < $pageall){
        $mess    .=\"?<a href=\"\".$urled.$strpage.\"=\".($page+1).\"\"> ></a>\";
        $mess    .=\"?<a href=\"\".$urled.$strpage.\"=\".$pageall.\"\"> >|</a>\";
    }else{
        $mess    .=\"? >\";
        $mess    .=\"?>|\";
    }
return $mess;
}

应用:
echo splitpage(1000,1,\"page.php\",\"p\",10);

Tags: 分页

乱了

陷入了迷茫。也许因为没有信仰吧。“不管你信仰什么,你必需有所信仰”《冲出宁静号》中,牧师临终时,如是说。
好多的事等着我去做,可是我没有想动手的念头。就这样慢慢又迅疾地让时间从手指间流走。冬天的阳光没能温暖我的情绪,不管怎样我总是感到冰冷。
已经到1月底了,可我没有过分的在意。总觉得春节过了,才是真正新的一年。于是彷徨着,等待着春节的到来。没有多少成绩,没有多少进步,更不想言语了。又隐隐的期盼着来年会有所长进。

ADODB入门(赞)

1. 前言
ADODB 是 Active Data Objects Data Base 的简称,它是一种 PHP 存取数据库的函式组件。
虽然 PHP 是建构 Web 系统强有力的工具,但是 PHP 存取数据库的功能,一直未能标准化,每一种数据库,都使用另一种不同且不兼容的应用程序接口(API)。为了填补这个缺憾,因此才有 ADODB 的出现。一旦存取数据库的接口予以标准化,就能隐藏各种数据库的差异,若欲转换至其它不同的数据库,将变得十分容易。

目前 ADODB 支持的数据库种类非常地多,例如:MySQL, PostgreSQL, Interbase, Informix, o&#114;acle, MS SQL 7, Foxpro, Access, ADO, Sybase, DB2 以及一般的 ODBC (其中 PostgreSQL、Informix、Sybase 的driver 是由自由软件社群发展之后贡献出来的)。

使用 ADODB 最大的优点之一是:不管后端数据库如何,存取数据库的方式都是一致的,开发设计人员不必为了某一套数据库,而必须再学习另一套不同的存取方法,这大大减轻开发人员的知识负担,过去的知识往后仍可继续使用,转移数据库平台时,程序代码也不必做太大的更动。

其实 ADODB 这样的发展理念,并不是首创的,DBI 比 ADODB 出现得更早,它提供 Perl 存取数据库时,使用一致的 API 呼叫接口。相信用过 Perl + DBI 的朋友,再来用 ADODB 时,会有一种似曾相识的感觉。

另外,ADODB 对用过 ASP 的人而言,应该不陌生,这类朋友对 ADODB 应该很容易接受。

我们来看一下,ADODB 的简单用法:
<?php
    // 引入 adodb 的 inc 档,才能呼叫 adodb 提供的函式
    include("adodb/adodb.inc.php");

    // 选择连接的数据库种类,以建立联机对象,
    // 一旦对象建立,即可使用其成员函式来处理数据库。
    // 以下 $conn 即此一物件(object)
    $conn = &amp;ADONewConnection("mysql");

    // 要不要显示侦错讯息,false 不要,true 要。
    // $conn->debug = false;
    
    $conn->debug = true;

    // 连接数据库
    // 用法:$conn->Connect("主机", "使用者", "密码", "数据库");
    // 用例:
    $conn->Connect("localhost", "piza", "ooo123", "test");

    // 若欲采用持续性连接,上式可换用 PConnect:
    // $conn->PConnect("localhost", "piza", "ooo123", "test");

    // 设定 sql 命令
    $sql = "ins&#101;rt into t values ("abcde", 18)";

    // 执行 sql 命令
    $rs = $conn->Execute($sql);

    // 检查执行结果,若 $rs == false,则呼叫 $conn 对象的成员函式 ErrorMsg()
    if (!$rs) print $conn->ErrorMsg(); else print "OK!";

?>

结果如下:
---------------------------------------------
(mysql): ins&#101;rt into t values ("abcde",18)
---------------------------------------------
OK!

若把侦错关掉,即 $conn->debug=false,则结果如下:
OK!

以下,逐步为各位介绍:使用 ADODB 的重点方法。

2. 安装
ADODB 的首页在:http://php.weblogs.com/ADO...,目前(2002/10/24)最新版是:2.42 版,可至 ADODB 下载或至台南县教网中心 FTP 下载。

安装 ADODB 的方法超极简单,只要下载、解压、放入适当位置,即可完成 ! 如下所示:

1. 下载:

$ ncftp ftp.tnc.edu.tw

  cd sysop/ADODB

  get adodb242.tgz

2. 解压:

假设我把 adodb242.tgz 放入 /var/www/html 中

$ cp adodb242.tgz /var/www/html

$ tar xvzf adodb242.tgz

如下所示:

adodb/adodb-cryptsession.php
adodb/adodb-csvlib.inc.php
adodb/adodb-errorhandler.inc.php
adodb/adodb-errorpear.inc.php
adodb/adodb-lib.inc.php
adodb/adodb-pager.inc.php
....以下省略....

现在,您在 /var/www/html/adodb 已安装好 ADODB 了。

3. 引入 ADODB
一旦安装好 ADODB,使用前,应把 ADODB 相关的含入文件引入您的程序中。adodb 目录放在任何位置无所谓,只要能指向正确路径文件名即可。一般而言,您的程序代码只须引入 adodb.inc.php。

作法如下:

在您的 PHP 程序中:

include("路径/adodb/adodb.inc.php");



include_once("路径/adodb/adodb.inc.php");

例:

若您的程序和 adodb 在同一目录下:

.
..
adodb/
something.php*

则:

include("adodb/adodb.inc.php");

即可。

若位置是在某一个目录 somedir 中:
.
..
adodb
somedir/something.php

则必须使用:
include("../adodb/adodb.inc.php");

除了 adodb.inc.php 这个含入档,ADODB 还提供许多 adodb-*.inc.php 的含入档,这些多半是为驱动某些数据库的特殊用法而设的。

若是引入 adodb-session.php 则可让您将 session 存入数据库中来维护运用。

若是引入 adodb-pager.inc.php,可方便您做分页显示。

若是引入 adodb-errorhandler.inc.php,可让您自订错误处理讯息。

若是含入 adodb-pear.inc.php,可让您使用 PHP4 的 PEAR DB 语法来使用 ADODB。此时,尚可使用 DSN 连接数据库的字符串设定。如 $dsn="mysql://piza:ooo123@localhost/test";

若是引入 tohtml.inc.php,可帮您在程序代码中,方便将取出的记录,转成 HTML 的表格(table)来显示。

若是引入 toexport.inc.php,可让您方便地输出 CSV 档或以 tab 分隔字段的数据文件。

若是引入 rsfilter.inc.php,可让您在使用记录之前,预做过滤处理。

若是引入 pivottable.inc.php,可让您使用 pivot table 功能(俗称 cross-tabulations)。

注意 ! adodb.inc.php 是一定要引入的,其它,则视您要使用那一个功能,再引入该含入档即可。

4. 选用数据库种类,建立联机对象
由于 ADODB 使用对象导向的作法,因此您在引入档之后,接着请视您后端数据库的种类,建立一个联机对象。作法如下:

以 MySQL 数据库为例:

    $conn = &amp;ADONewConnection("mysql");

注:NewADOConnection 和 ADONewConnection 是一样的,二者皆可使用。

上例中的 "mysql" 是指数据库的 drvier 的种类,ADODB 会据此呼叫对应的数据库 driver。

其它常用的 driver 有:access、ado、ado_access、ado_mssql、db2、vfp、ibase、borland_ibase、informix、imformix72、mssql、oci8、odbc、postgres、postgres64、postgres7、sqlanywh&#101;re、sybase....等等。

我们称建立的对象 $conn 为一 ADOConnection 对象,它代表与数据库的连接事务,皆透过这个对象来处理。ADOConnection 对象会提供许多处理的方法,以对象导向的说法,这些方法称为成员函式,这是外界存取此一对象的接口。

一旦联机对象建立之后,就有许多对象函式可供您使唤啦 ! 请看下一节的介绍。

5. 侦错模式
程序开发的过程,为了方便查出出现问题可能的地方,通常我们会打开侦错模式,俟程序功能确实稳定之后,再将它关闭。ADODB 提供侦错模式,存取数据库时,能显示其运作方式。

打开侦错模式,使用法:

$conn->debug=true

关闭侦错模式,使用法:

$conn->debug=false

6. 连接数据库
接着,使用 $conn 联机对象的 Connect 或 PConnect 函式来连接特定的数据库,此时必须提供 DSN (Data Source Names)相关数据,DSN 可能包括:主机名称、数据库使用者、数据库密码、数据库名称。不同的数据库种类,DSN 可能可以省略其中若干项。以 MySQL 而言,则上述四者都要提供。

该函式会传回 true 或 false,用以表示是否连接成功。

用例:

// 格式:$conn->Connect("主机", "使用者", "密码", "数据库");

    $conn->Connect("localhost", "piza", "ooo123", "test");

或者,采持续性连接:

// 格式:$conn->PConnect("主机", "使用者", "密码", "数据库");

    $conn->PConnect("localhost", "piza", "ooo123", "test");


若欲探查是否有联机成功,可用一个变量来接取传回值:

$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

$cok = $conn->Connect($mch, $user, $pwd, $database);

或者,采持续性连接:

$cok = $conn->PConnect($mch, $user, $pwd, $database);

if (!$cok) { echo "无法连接数据库 $database"; exit; }

7. 设定 sql 命令语法、执行 sql 命令
接下来,您就可以设计您要执行的 sql 命令语法,然后付诸执行。

$sql = "这里放 SQL 的命令语法";

$rs = $conn->Execute($sql);

其中,$rs 为回传的结果,若 $rs == false,则表示执行失败,您必须仔细检查一下。

您不一定要把命令语法放在 $sql 变量中,也可以直接放入 Execute( ) 括号中。若命令较短无妨,若命令较长,我建议您还是用一个变量 $sql 来设定命令字符串吧 !

下一节开始,为各位介绍 SQL 的基本命令,如:Ins&#101;rt、Sel&#101;ct、Up&#100;ate、Del&#101;te 等等的用法。

8. 插入记录(Ins&#101;rt)
Ins&#101;rt 的用法如下:
// $name 为字符串,$year 为数字
$name="abcde";
$year=18;

// 插入一笔记录,命令的大小写无妨,但数据表 t 及变量则大小写有分别 !
$sql = "Ins&#101;rt INTO t VALUES ("$name", $year)";

// $sql = "ins&#101;rt into t values ("$name", $year)"; 亦可。

// 执行
$rs = $conn->Execute($sql);

// 检查执行结果,进行错误处理;若正常,则继续其它动作....
if (!$rs) print $conn->ErrorMsg();

....以下省略....

ErrorMsg() 是错误显示的函式,它会取出错误讯息,并显示出来。

另外,ADODB 提供一种 记录集(RecordSet) 函式 GetIns&#101;rtSQL(),可帮您产生 Ins&#101;rt 的语法。

例子如下:

<?php

// 引入 ADODB
include("adodb/adodb.inc.php");

// 建立联机对象
$conn = &amp;ADONewConnection("mysql");

// 侦错
$conn->debug=true;

// DSN 四项基本数据设定
$mch="localhost";
$user="root";
$pwd="jack168";
$database="test";

// 连接至数据库 test
$conn->PConnect($mch, $user, $pwd, $database);

// 产生一笔空记录
$sql = "sel&#101;ct * from t wh&#101;re year=-1";

$rs = $conn->Execute($sql);


// 用一个空数组来装要更新的数据
$r = array();

$r["name"]="john";
$r["year"]=28;

// 用 GetIns&#101;rtSQL 函式来制作一个完整的 sql 命令,此 sql 命令放在 $ins&#101;rtSQL 中
$ins&#101;rtSQL = $conn->GetIns&#101;rtSQL($rs, $r);

// 执行插入
$conn->Execute($ins&#101;rtSQL);

$conn->Close();
?>

侦错讯息如下:

-----------------------------------------------------------
(mysql): sel&#101;ct * from t wh&#101;re year=-1
-----------------------------------------------------------
(mysql): Ins&#101;rt INTO t ( name, year ) VALUES ( "john", 28 )
-----------------------------------------------------------    

9. 取出记录(Sel&#101;ct)
Sel&#101;ct 的用法如下:
<?php

// 引入 ADODB
include("adodb/adodb.inc.php");

// 建立联机对象
$conn = &amp;ADONewConnection("mysql");

// 不侦错
$conn->debug=false;

// DSN 四项基本数据设定
$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

// 连接至数据库 test
$conn->PConnect($mch, $user, $pwd, $database);

// 执行 Sel&#101;ct 由表格 t 取出数据,
// 它会传回一个 ADORecordSet 记录集对象 $rs (RecordSet)
// 实际上 $rs 是一个 cursor 指标,它拥有目前的记录(row 或称 record),
// 该记录的所有字段数据的内容,存放在 fields 这个数组之中
// ,以数字为索引,第一个由 0 开始
$rs = &amp;$conn->Execute("sel&#101;ct * from t");

// 若 $rs 为 false,则秀出错误讯息
if (!$rs) {
    print $conn->ErrorMsg();
} else {

// 当尚未到达 记录集 $rs 的结束位置(EOF:End Of File)时,(即:还有记录尚未取出时)
    while (!$rs->EOF) {
        // 秀出所有字段,$FieldCount() 会传回字段总数
    for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
        print $rs->fields[$i] . " ";
    }

        // 移至下一笔记录
    $rs->MoveNext();
    
    // 换列
    echo "<br>\n";
    }
}

$rs->Close(); // 可不用
$conn->Close(); // 可不用
?>

$rs->fields[] 数组是由 PHP 的数据库扩展功能产生的,某些扩展功能并不支持使用字段名称当作索引。

若欲使用名称当作索引,也就是俗称的 hash 或 associative arrays,则需使用全域变量 $ADODB_FETCH_MODE 加以指定。

以下设定:使用数字索引 $ADODB_FETCH_MODE= ADODB_FETCH_NUM;

以下设定:使用名称索引 $ADODB_FETCH_MODE= ADODB_FETCH_ASSOC;

下面是使用名称索引的例子:

<?php

// 引入 ADODB
include("adodb/adodb.inc.php");

// 建立联机对象
$conn = &amp;ADONewConnection("mysql");

// 不侦错
$conn->debug=false;

// DSN 四项基本数据设定
$mch="localhost";
$user="root";
$pwd="jack168";
$database="test";

// 连接至数据库 test
$conn->PConnect($mch, $user, $pwd, $database);

// 执行 sql 之前,指定使用名称索引
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;

// 执行 Sel&#101;ct,它会传回一个 ADORecordSet 记录集对象 $rs
// 实际上 $rs 是一个 cursor 指标,它拥有目前的记录内容,
// 该记录存放在 fields 这个数组之中
$rs = &amp;$conn->Execute("sel&#101;ct * from t");

// 若 $rs 为 false,则秀出错误讯息
if (!$rs) {
    print $conn->ErrorMsg();
} else {

// 当尚未到达记录集结束位置(EOF)时,
    while (!$rs->EOF) {
        // 秀出所有字段

    print $rs->fields["name"] . " " . $rs->fields["year"];

        // 移至下一笔记录
    $rs->MoveNext();
    
    // 换列
    echo "<br>\n";
    }
}

$rs->Close();  // 可不用
$conn->Close(); // 可不用
?>

10. 取出记录(使用 FetchRow)
这里示范 FetchRow 的用法:

$sql = "sel&#101;ct * from t";

$rs = $conn->Execute($sql);

if ($rs) {
    while( $ar = $rs->FetchRow() ) {
        print $ar["name"] ." " . $ar["year"];
        print "<br>\n";
    }

}

FetchRow() 会将取出的记录传回,您可用一个 array 来接取。

注意 ! 使用 FetchRow() 就不必再用 MoveNext(),FetchRow 内部会自动完成移至下一笔记录的动作。

11. 更新记录(Up&#100;ate)
您可以用传统的方式:

$sql ="Up&#100;ate t SET name="john", year=28 Wh&#101;re year=18";
$conn->Execute($sql);

也可以用以下这种方式:

<?php

// 引入 ADODB
include("adodb/adodb.inc.php");

// 建立联机对象
$conn = &amp;ADONewConnection("mysql");

// 侦错
$conn->debug=true;

// DSN 四项基本数据设定
$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

// 连接至数据库 test
$conn->PConnect($mch, $user, $pwd, $database);

// 选择要更新的那一笔记录
$sql = "sel&#101;ct * from t wh&#101;re year=18";

$rs = $conn->Execute($sql);


// 用一个空数组来装要更新的数据
$r = array();

$r["name"]="john";
$r["year"]=28;

// 用 GetUp&#100;ateSQL 函式来制作一个完整的 sql 命令,此 sql 命令放在 $up&#100;ateSQL 中
$up&#100;ateSQL = $conn->GetUp&#100;ateSQL($rs, $r);

// 执行更新
$conn->Execute($up&#100;ateSQL);

$conn->Close();
?>

侦错讯息如下:

-------------------------------------------------------------
(mysql): sel&#101;ct * from t wh&#101;re year=18
-------------------------------------------------------------
(mysql): Up&#100;ate t SET name = "john", year = 28 Wh&#101;re year=18
-------------------------------------------------------------

12. 删除记录(Del&#101;te)
删除记录很简单,采传统方式即可: $sql = "Del&#101;te FROM t Wh&#101;re year=18";

$rs = $conn->Execute($sql);

13. 使用字段对象(Field Objects)
这里示范字段对象 FetchField 的用法,用以取得字段名称及字段型态:

$sql = "sel&#101;ct * from t";

$rs = &amp;$conn->Execute($sql);

if ($rs) {
   while (!$rs->EOF) {
    // 取出第二个字段
    $f = $rs->FetchField(1);

    // 印出字段名称 及 字段型态
    print $f->name . ":" . $f->type;

    $rs->MoveNext();

    print "<br>\n";
   }
}

另外,ADODB 提供一个 RecordSet 函式 MetaType(),可将原始的字段型态转成一般型态代码:

C : 字符
X : text
B : blob
D : 日期
T : timestamp
L : 布尔值或位
I : 整数
N : 数字型态,包括:自动增加、数值、浮点数、实数及整数
R : serial、自动增加

用例:
    $f = $rs->FetchField(1);

    // 印出字段名称 及 字段型态的代码
    print $f->name . ":" . $rs->MetaType($f->type);

14. 简单分页(Pager)
ADODB 提供一种简单分页显示记录的方法,使用前,要将 adodb-pager.inc.php 引入。

<?php

include("adodb/adodb.inc.php");

// 引入分页功能
include("adodb/adodb-pager.inc.php");

// 启动 session
session_start();

$db = ADONewConnection("mysql");

$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

$db->Connect($mch, $user, $pwd, $database);

$sql = "sel&#101;ct * from t";

// 产生 pager 对象
$pager = new ADODB_Pager($db, $sql);

// 每一页秀 5 笔记录
$pager->Render($rows_per_page=5);

?>

结果如下:
点击在新窗口中浏览此图片
Figure 1. 简单分页功能

每页显示记录的数目是由 Render() 来控制的,若没有传入指定的 row 数给 Render(),默认值每页秀 10 笔。

另外,字段名称也可以改变,如下示范:

<?php

include("adodb/adodb.inc.php");

// 引入分页功能
include("adodb/adodb-pager.inc.php");

// 启动 session
session_start();

$db = ADONewConnection("mysql");

$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

$db->Connect($mch, $user, $pwd, $database);

$sql = "sel&#101;ct name as "姓名", year as "年纪" from t";

// 产生 pager 对象
$pager = new ADODB_Pager($db, $sql);

// 每一页秀 5 笔记录
$pager->Render($rows_per_page=5);
?>

结果如下:
点击在新窗口中浏览此图片
Figure 2. 改变字段名称

15. 输出 CSV 档
ADODB 提供输出 CSV 档的方法,使用前,要将 toexport.inc.php 引入。
<?php

include("adodb/adodb.inc.php");

// 引入输出 CSV 文件功能
include("adodb/toexport.inc.php");

$db = ADONewConnection("mysql");

$mch="localhost";
$user="piza";
$pwd="ooo123";
$database="test";

$db->Connect($mch, $user, $pwd, $database);

$sql = "sel&#101;ct name as "姓名", year as "年纪" from t";

$rs = $db->Execute($sql);

// 秀出 CSV 格式
print rs2csv($rs);
?>

结果如下:

姓名,年纪
abcde,45
yyy,20
ppp,34
mmm,13
hhh,41
rrr,65
kkk,29
miso,154
sss,89
abc,18
abcde,0
uyt,58
john,28

也可用 tab 分隔字段,使用 rs2tab 方法如下:

print rs2tab($rs, false);

注: false 表示不显示字段名称

结果如下:

abcde  45
yyy    20
ppp    34
mmm    13
hhh    41
rrr    65
kkk    29
miso   154
sss    89
abc    18
abcde  0
uyt    58
john   28

若是 print rs2tab($rs, true);
结果如下:

姓名    年纪
abcde   45
yyy     20
ppp     34
mmm     13
hhh     41
rrr     65
kkk     29
miso    154
sss     89
abc     18
abcde   0
uyt     58
john    28

也可以将结果由标准输出(STDOUT)显示,使用 rs2tabout 方法如下:

print rs2tabout($rs);

执行结果如下:
点击在新窗口中浏览此图片
Figure 1. 在console中显示结果

也可以存成 CSV 档:

// 档案路径
$path = "/tmp/test.csv";

// 开档供写入
$fhd = fopen($path, "w");

// 若开档成功
if ($fhd) {

   // 则写入 CSV
   rs2csvfile($rs, $fhd);

   // 也可以使用 rs2tabfile($rs, $fhd);

   // 关档
   fclose($fhd);
}

结果如下:

[ols3@p web]$ cat /tmp/test.csv
姓名,年纪
abcde,45
yyy,20
ppp,34
mmm,13
hhh,41
rrr,65
kkk,29
miso,154
sss,89
abc,18
abcde,0
uyt,58
john,28

16. 取出一定笔数的记录 (使用 Sel&#101;ctLimit)
ADODB 提供一个 ADOConnect 函式 Sel&#101;ctLimit,可供您取出一定笔数的记录,用法如下:

$conn->Connect($mch, $user, $pwd, $database);

rs = $conn->Sel&#101;ctLimit("Sel&#101;ct * from t", 3, 1);
//                             取出 3 笔、在第 1 笔之后

// 秀出这 3 笔记录
if ($rs) {
    while( $ar = $rs->FetchRow() ) {
        print $ar["name"] ." " . $ar["year"];
        print "<br>\n";
    }

}

上式是说:在第 1 笔记录之后,取出 3 笔,也就是第 2、3、4 笔记录。

结果如下:
--------------------------------------
(mysql): sel&#101;ct * from t LIMIT 1,3
--------------------------------------
注意 ! Sel&#101;ctLimit 的写法刚好和 MySQL 语法相反 !

17. 结语
本讲义,主要是为:有心参与 SFS3 (sfs.wpes.tcc.edu.tw) 计划的伙伴们而写的。做为一份入门文件,以上这些介绍,应该是足够让您了解 ADODB 并且能把它应用在 SFS3 或其它有意义的地方了吧? 若果真如此,小弟就心满意足了 !

ref. 参考资源
ADODB 网站
ADODB 手册
PHP 对象导向入门

Tags: adodb

给图片添加水印(支持中文)并生成缩略图

代码:
// **************************************** //
// 功能:给图片添加水印(支持中文)并生成缩略图
// 作者: 乐言 (qq:7928478)
// 参数: $srcFile 图片文件名
// $dstFile 另存图片文件名
// $markwords 水印文字内容
// $markimage 水印图片地址
// $dstW 图片保存宽度
// $dstH 图片保存高度
// $rate 图片保存品质
// **************************************** //
function makethumb($srcFile,$dstFile,$dstW,$dstH,$rate=100,$markwords=null,$markimage=null)
{
$data = GetImageSize($srcFile);
switch($data[2])
{
case 1:
$im=@ImageCr&#101;ateFromGIF($srcFile);
break;
case 2:
$im=@ImageCr&#101;ateFromJPEG($srcFile);
break;
case 3:
$im=@ImageCr&#101;ateFromPNG($srcFile);
break;
}
if(!$im) return False;
$srcW=ImageSX($im);
$srcH=ImageSY($im);
$dstX=0;
$dstY=0;
if ($srcW*$dstH>$srcH*$dstW)
{
$fdstH = round($srcH*$dstW/$srcW);
$dstY = floor(($dstH-$fdstH)/2);
$fdstW = $dstW;
}
else
{
$fdstW = round($srcW*$dstH/$srcH);
$dstX = floor(($dstW-$fdstW)/2);
$fdstH = $dstH;
}
$ni=ImageCr&#101;ateTrueColor($dstW,$dstH);
$dstX=($dstX<0)?0:$dstX;
$dstY=($dstX<0)?0:$dstY;
$dstX=($dstX>($dstW/2))?floor($dstW/2):$dstX;
$dstY=($dstY>($dstH/2))?floor($dstH/s):$dstY;
$white = ImageColorAllocate($ni,255,255,255);
$black = ImageColorAllocate($ni,0,0,0);
imagefilledrectangle($ni,0,0,$dstW,$dstH,$white);// 填充背景色
ImageCopyResized($ni,$im,$dstX,$dstY,0,0,$fdstW,$fdstH,$srcW,$srcH);

// 生成水印
if($markwords!=null)
{
$markwords=iconv("gb2312","UTF-8",$markwords);
//转换文字编码
ImageTTFText($ni,9,0,10,15,$white,"simhei.ttf",$markwords);
//ImageTTFText(int im,int size,int angle,int x,int y,int col,string fontfile,string text):
//本函数将 TTF (TrueType Fonts) 字型文字写入图片。
//参数: size 为字形的尺寸;
// angle 为字型的角度,顺时针计算,0 度为水平(由左到右),90 度则为由下到上的文字;
// x,y 二参数为文字的坐标值 (原点为左上角);
// col 为字的颜色;
// fontfile 为字型文件名称;
// text 是字符串内容。
}
elseif($markimage!=null)
{
$wimage_data = GetImageSize($markimage);
switch($wimage_data[2])
{
case 1:
$wimage=@ImageCr&#101;ateFromGIF($markimage);
break;
case 2:
$wimage=@ImageCr&#101;ateFromJPEG($markimage);
break;
case 3:
$wimage=@ImageCr&#101;ateFromPNG($markimage);
break;
}
imagecopy($ni,$wimage,0,0,0,0,88,31);
imagedestroy($wimage);
}

ImageJpeg($ni,$dstFile,$rate);
imagedestroy($im);
imagedestroy($ni);
//结束图形,释放内存空间
}

Tags: 水印, 缩略图

Records:23123