PHP 5数据对象(PDO)抽象层与Oracle

 更新时间:2016年11月25日 16:29  点击:1964

名新 PHP 数据对象 (PDO) 数据抽象层的原始开发人员为您简要介绍该抽象层,重点讲述与 Oracle 一起运行的情况。
  需要 PHP:5.0
  需要其他:Oracle 8 或更高版本客户端库
  下载用于 Oracle 的 PDO (Windows):php_pdo.dll, php_pdo_oci.dll
  下载用于 Oracle 的 PDO (Unix):pdo, pdo_oci
  PDO 简介
  PHP 主要是由志愿者完成的项目;尽管有少数一些固定的“核心”开发人员,但是我们没有一个人在全职受薪的开发 PHP。除此之外,我们分别位于世界不同地方,您可以想象长期开发的协调工作是何等困难。因此,PHP 主要是基于突发奇想的个人短期需求来发展的,其原因也多种多样,有的是试验,有的则是因为“明天有活要交”。尽管这样通常每一步都会改善 PHP,但从长远来看则是缺乏完整性 - 数据库教程扩展就是一个重要的例子。
  在各种不同的数据扩展(oci、mysqlpostgresql、mssql 等)之间根本没有真正的一致性,甚至在某些情况下,在这些扩展内部也没有真正的一致性。几乎所有这些扩展都在使用与基础数据库 API 紧密相连的不同代码完成着相同种类的任务。而且因为我们(PHP 核心开发人员和扩展开发人员)的人手非常有限,因此这就造成了代码更加难以维护,从而为 PHP 带来了很大的问题。
  由于 PHP 越来越受欢迎并不断成功,因此主要 PHP 数据库扩展的维护者们参加了在德国举行的 LinuxTag 2003 大会,在会上我们交换了对 PHP 前景的看法。在讨论 PHP 发展的随机性时,我们确定了在 PHP 中进行数据库访问的一些目标:
  ·提供一种轻型、清晰、方便的 API
  ·统一各种不同 RDBMS 库的共有特性,但不排除更高级的特性。
  ·通过 PHP 脚本提供可选的较大程度的抽象/兼容性。
  我们之所以提出了这种 PHP 数据对象 (PDO) 的概念,是因为我们希望通过采用 Zend Engine 2(PHP 5 的核心)先进的面向对象特性获得该 API 的一些更优秀的性能。
  PHP 中的数据抽象层概念一点都算不上新;在 Google 中查询“PHP database abstraction”会找到大约 83,200 个匹配项。它几乎是许多 PHP 开发人员梦寐以求的,而其产生则部分归因于我们不完整的 API。如果您曾经尝试过使用第三方抽象层来完成任何真正重要的工作,通常会发现这些抽象层对于手头的工作来说设计的功能过于强大了 - 或者表现为在使用前需要进行大量学习,或者表现为接口速度缓慢,参数需要经过多层脚本函数调用才能到达数据库自有的 API;通常是存在上述两种表象。
  为什么这些抽象层会存在这种问题?这些抽象层总是在试图完成太多的任务,甚至可能是不可能的任务。我们决定以实用为目标,仅将一些最常见的数据库 API 特性作为我们的基础,并使得 PDO 驱动程序能够将它们特定于产品的特性暴露为常规扩展函数。
  为什么使用 PDO?
  听过有关数据库抽象扩展谣传的大多数人会立刻对 PDO 的扩展方面产生疑惑 - 我们是否要分析 SQL,将其转换为相应的后端方言呢?我们如何处理特性 X 或特性 Y,等等。因此,当您听说我们在 PDO 中根本不用为此而担忧时可能会大吃一惊;我们不希望使所有内容都完全统一,因为要使得这种统一成为可能,只能是将自己限制在最低的通用标准。
  如果 PDO 不是一个整体的抽象层,那还有什么别的原因值得您考虑使用它吗?
  ·性能。PDO 从一开始就吸取了现有数据库扩展成功和失败的经验教训。因为 PDO 的代码是全新的,所以我们有机会重新开始设计性能,以利用 PHP 5 的最新特性。
  ·能力。PDO 旨在将常见的数据库功能作为基础提供,同时提供对于 RDBMS 独特功能的方便访问。
  ·简单。PDO 旨在使您能够轻松使用数据库。API 不会强行介入您的代码,同时会清楚地表明每个函数调用的过程。
  ·运行时可扩展。PDO 扩展是模块化的,使您能够在运行时为您的数据库后端加载驱动程序,而不必重新编译或重新安装整个 PHP 程序。例如,PDO_OCI 扩展会替代 PDO 扩展实现 Oracle 数据库 API。还有一些用于 MySQL、PostgreSQL、ODBC 和 Firebird 的驱动程序,更多的驱动程序尚在开发。
  您可能想了解 PDO 与其他常用的抽象层的对比情况,例如 PEAR DB 或 ADODB。无论在 API 方面还是在性能方面,PDO 都比其他常见抽象层要轻型,但是涉及到在各个数据库后端之间提供统一性方面,则不如那些抽象层,例如用于处理大量可移植性问题的 PEAR MDB 2 抽象层。

function fPageCount($TotalResult,$numPerPage,$Page){
    $NaviLength='10' ; //显示数量
    $showMorePageGo_Type_=0; //跳转样式
    $int_showNumberLink_='十';
    $nonLinkColor_="#999999";
    $toF_="<font face=webdings title='首页'>9</font>" ;
    $toP10_=" <font face=webdings title='上十页'>7</font>";
    $toP1_=" <font face=webdings title='上一页'>3</font>";
    $toN1_=" <font face=webdings title='下一页'>4</font>";
    $toN10_=" <font face=webdings title='下十页'>8</font>";
    $toL_="<font face=webdings title='最后一页'>:</font>";
    $page_index = "";

    $tpagecount = ceil($TotalResult/$numPerPage);
$nowCoolPage=ceil($Page/$NaviLength);
    $toPage_ = $_SERVER['QUERY_STRING'];
    if ( $toPage_ == '' ) {
       $toPage_ = "?page=";本人原创php通用翻页类,支持上*页和下*页..
    }else {
       $toPage_ = preg_replace("/&?page=d+/", '', $toPage_);
       $toPage_ = "?".$toPage_."&page=";
    }
     
if($nowCoolPage == 1){
        $page_index.="<font color=".$nonLinkColor_." title='首页'>".$toF_."</font> ";
        $page_index.="<font color=".$nonLinkColor_." title='上".$int_showNumberLink_."页'>".$toP10_."</font> ";
    }else{
        $preRow =  $Page-$NaviLength;
  $page_index.="<a href=".$toPage_."1 title='首页'>".$toF_."</a> ";
  $page_index.="<a href=".$toPage_.$preRow." title='上".$int_showNumberLink_."页'>".$toP10_."</a> ";
    }
    $upRow   = $Page-1;
    $downRow = $Page+1;
    if ($upRow>0){
       $page_index.="<a href=".$toPage_.$upRow." title='上一页'>".$toP1_."</a> ";
    }else{
       $page_index.="<font color=".$nonLinkColor_." title='上一页'>".$toP1_."</font> ";
    }
     
for($i=1;$i<=$NaviLength;$i++){
         $nowPage=($nowCoolPage-1)*$NaviLength+$i;
         if($nowPage!=$Page){
             if($nowPage<=$tpagecount){
                 $page_index.="  <a href=".$toPage_.$nowPage.">" .$nowPage. "</a> ";
             }else{
                 break;
             }
         }else{
             if($tpagecount != 1){
                $page_index.="<b>".$nowPage."</b>";
             }
         }
      }
     if ($downRow <= $tpagecount){
         $page_index.="<a href=".$toPage_.$downRow." title='下一页'>".$toN1_."</a> ";
     }else{
         $page_index.="<font color=".$nonLinkColor_." title='下一页'>".$toN1_."</font> ";
     }
     if($nowCoolPage == $tpagecount){
         $page_index.=" <font color=".$nonLinkColor_." title='下".$int_showNumberLink_."页'>".$toN10_."</font> ";
         $page_index.="<font color=".$nonLinkColor_." title='尾页'>".$toL_."</font>";
     }else{
         $nextRow = $Page+$NaviLength;
         $theEndRow = $tpagecount;
         $page_index.=" <a href=".$toPage_.$nextRow." title='下".$int_showNumberLink_."页'>".$toN10_."</a> ";
         $page_index.="<a href=".$toPage_.$theEndRow." title='尾页'>".$toL_."</a>";
     }
    if ($showMorePageGo_Type_ ==1){
      $Show_Page_i = $Page + 1 ;
    if ($Show_Page_i>$tpagecount) $Show_Page_i = 1;
    $page_index.="  跳转<input type='text' id='skip' value='' onkeyup='this.value=this.value.replace(/[^d]+/,'')' style='width:40px'/>  <input type='button' value='确定' class='btn' onclick='location.href='?page='+$('skip').value+'".$toPage_."';'/>n";
       }else{
       $page_index.=" 跳转:<select name='select' size='1' style='font-size: 12px' onchange='javascript:window.location.href=this.options[this.selectedIndex].value'>";
     for($i=1;$i<=$tpagecount;$i++){
     if($Page==$i){
        $selected=" selected";
     }else{
        $selected="";
        }
        $page_index.=" <option value=".$toPage_.$i;
        $page_index.=$selected." style='color:#FF0000'";
        $page_index.=">第".$i."页</option>";
     }
        $page_index.="</select>";
   }
        $page_index.=$p_.$sp2_."  每页<b>".$numPerPage."</b>个记录,现在是:<b><span class='tx'>".$sp2_.$Page."</span>/".$tpagecount."</b>页,共<b><span id='recordcount'>".$sp2_.$TotalResult."</span></b>个记录。";
    return $page_index;
}


例子:<?php echo fPageCount($TotalResult,$numPerPage,$page)?>   $TotalResult 代表总数 $numPerPage 每页显示数量 $page 页码

1、如何正确的创建一个网站的Index页面
创建每一个网站时,建立网站的index页面是首要做的事情之一。如果你是一个PHP新手,在编写index页面时典型的做法是只对index页面所需的内容进行编程,其它链接创建另一个页面。不过,如果想学习一种更高效的方式来实现PHP编程,可以采用“index.php?page=home”模式,许多网站都在采用这种模式。
2、使用Request Global Array抓取数据
实际上我们没有任何理由使用$_GET和$_POST数组来抓取数值。$_REQUEST这个全局数组能够让你获取一个get或form请求。因此,多数情况下解析数据的更高效代码大体如下:
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 0;  3、利用var_dump进行PHP代码调试
如果你在寻找php调试技术,我必须说var_dump应该是你要找的目标。在显示php信息方面这个命令可以满足你的所有需要。而调试代码的多数情况与得到PHP中的数值有关。
4、PHP处理代码逻辑,Smarty处理展现层
Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目的就是要使PHP程序员同前端人员分离,使程序员改变程序的逻辑内容不会影响到前端人员的页面设计,前端人员重新修改页面不会影响到程序的程序逻辑,这在多人合作的项目中显的尤为重要。
5、的确需要使用全局数值时,创建一个Config文件
动辄创建全局数值是一种糟糕的做法,不过有时候实际情况的确又需要这么做。对于数据库教程表或数据库连接信息使用全局数值是一个不错的想法,但不要在你的PHP代码中频繁使用全局数值。另外,更好的一种做法是把你的全局变量存放在一个config.php文件中。
6、如果未定义,禁止访问!
如果你正确的创建了页面,那么任何其他人没有理由访问index.php或home.php之外的index.php页面。一旦index.php被访问后,你可以通过获得变量的方式来打开需要的页面。你的index页面应该包含类似的以下代码:
define('yourPage',1); 然后,其它页面应该包含:
if (!defined('yourPage')) die('Access Denied'); 这么做的目的是防止直接访问你的其它php页面。这样,任何试图不通过index.php访问其它网页的人,将得到“访问被拒绝”的消息。
7、创建一个数据库类
如果你正在进行数据库编程(在PHP中非常常见的任务),一个不错的想法是创建一个数据库类来处理任何数据库管理功能。示例代码如下:
public function dbExec($query)      {          $result = $this->db->exec($query);          if (PEAR::isError($result))              errorRedirect($result->getMessage(), true);          else             return $result;      }  这个函数仅接收一个查询语句并对其执行。它还处理可能出现的任何错误。你还可以在这儿包含审核代码,不过我更喜欢使用一个类似的审核函数:
// checks if arguments given are integer values not less than 0 - has multiple arguments      function sanitizeInput()      {          $numargs = func_num_args();          $arg_list = func_get_args();          for ($i = 0; $i < $numargs; $i++) {              if (!is_numeric($arg_list[$i]) || $arg_list[$i] < 0)                  errorRedirect("Unexpected variable value", true);          }      }  8、一个php文件处理输入,一个class.php文件处理具体功能
不让代码变得混乱的一个重要方法是:获取用户输入后,将其重定向到其它函数来进行处理。原理非常简单,php文件获得我们需要的任何输入,然后将其执行重定向到类文件中的一个函数。举例来讲,假设有一个类似“index.php?page=profile&action=display”的URL。由profile.php来检索该网址并得到操作是“display”。然后使用一个简单的switch函数,我们来执行真正的显示函数:
require_once PROJECTROOT.'libs/messages.class.php';      $message = new Message();      switch ($action)    {        case 'display':            $message->display();            break;      ... 如上所示,我使用了一个消息类,然后开始进行switch检查。$message只是被类中的调用函数使用的一个对象。
9、了解你的SQL语句,并总是对其审查(Sanitize)
正如我以前所提到的,任何php网站中最重要的部分有99%的可能是数据库。因此,你需要非常熟悉如何正确的使用sql。学会关联表和更多高级技术。下面我将展示一个使用MySQL的函数示例,并使用本文第7条函数进行审查。
private function getSentMessages($id)      {     $this->util->sanitizeInput($id);         $pm_table = $GLOBALS['config']['privateMsg'];      $users = $GLOBALS['config']['users'];          $sql = "SELECT PM.*, USR.username as name_sender FROM $pm_table PM, $users USR              WHERE id_sender = '$id' AND sender_purge = FALSE AND USR.id = PM.id_receiver AND is_read = TRUE              ORDER BY date_sent DESC";      $result = $this->dbQueryAll($sql);         return $result;      }  首先,我们对用户输入进行检查(通过一个GET变量传递消息id),然后我们执行我们的SQL命令。注意这儿SQL的用法。你需要了解如何使用别名和关联表。
10、当你只需要一个对象时,使用单例模式
在PHP中相当常见的一种情形时,我们只需要创建一个对象一次,然后在我们的整个程序中使用它。一个很好的例子就是smarty变量,一旦被初始化后就可以在任何地方使用。这种情形的一个很好实现方案就是单例模式。示例代码如下:
function smartyObject()      {          if ($GLOBALS['config']['SmartyObj'] == 0)          {              $smarty = new SmartyGame();              $GLOBALS['config']['SmartyObj'] = $smarty;          }          else             $smarty = $GLOBALS['config']['SmartyObj'];          return $smarty;      }  注意,我们拥有一个全局smarty变量(该示例中它在config.php中被初始化),如果它的值为0,我们将创建一个新smarty对象。否则,它意味着该对象已经被创建,我们只需要返回它。

我们这个做法是把搜索结果出来,与搜索关键词相同的替换成高亮的字, 我们会用到str_replace(你找的关键字,<带有高亮的html标签>你找的关键字,$str);

  就这么容易了,好了下面我们来看一个实例吧。
 
  先创建一个数据库教程 create database 'searchKey';
  再创建表
 
  CREATE TABLE `fangke_cc`.`search` (
 `id` INT( 4 ) NOT NULL AUTO_INCREMENT ,
 `keyword` VARCHAR( 20 ) NOT NULL ,
 PRIMARY KEY ( `id` )
 ) ENGINE = MYISAM

 我们导入一些数据
 
 
 INSERT INTO `search` (`id`, `keyword`) VALUES
(1, '中国WEB第一站www.111cn.net'),
(2, '中国WEB第一站www.111cn.net'),
(3, '中国WEB第一站www.111cn.net'),
(4, '中国WEB第一站www.111cn.net');

好了下面我们就来执行查询操作
*/
if( $_POST) {

 $db ='fangke_cc';
 mysql教程_pconnect('localhost','root','root') or die(mysql_error());
 mysql_select_db($db);
 mysql_query("set names 'gbk'");  
 $key = $_POST['keyword'];
 $sql = "Select * from search where keyword like '%$key%'";
 $query = mysql_query($sql);
 while( $rs = mysql_fetch_array( $query ) )
 {
  echo str_replace($key,"<b>$key</b>",$rs['keyword']),'<br />';
 }
 /*
  中国WEB第一站www.<b>111cn</b>.net<br />
  中国WEB第一站www.<b>111cn</b>.net<br />
  中国WEB第一站www.<b>111cn</b>.net<br />
  中国WEB第一站
 */
}

?>
<form name="form1" method="post" action="">
  <label>
  <input name="keyword" type="text" id="keyword">
  </label>
  <label>
  <input type="submit" name="Submit" value="提交">
  </label>
</form>

注明:本文章原创于www.111cn.net  转载注明出处

function xiazai($file_dir,$file_name)
//参数说明:
//file_dir:文件所在目录
//file_name:文件名
{
     $file_dir = chop($file_dir);//去掉路径中多余的空格
     //得出要下载的文件的路径
     if($file_dir != '')
     {
         $file_path = $file_dir;
         if(substr($file_dir,strlen($file_dir)-1,strlen($file_dir)) != '/')
             $file_path .= '/';
         $file_path .= $file_name;
     }           
     else
         $file_path = $file_name;   
   
     //判断要下载的文件是否存在
     if(!file_exists($file_path))
     {
         alert('对不起,你要下载的文件不存在');
         return false;
     }

     $file_size = filesize($file_path);

     header("Content-type: application/octet-stream;charset=gbk");
     header("Accept-Ranges: bytes");
     header("Accept-Length: $file_size");
     header("Content-Disposition: attachment; filename=".$file_name);
   
     $fp = fopen($file_path,"r");
     $buffer_size = 1024;
     $cur_pos = 0;
   
     while(!feof($fp)&&$file_size-$cur_pos>$buffer_size)
     {
         $buffer = fread($fp,$buffer_size);
         echo $buffer;
         $cur_pos += $buffer_size;
     }
   
     $buffer = fread($fp,$file_size-$cur_pos);
     echo $buffer;
     fclose($fp);
     return true;

}

[!--infotagslink--]

相关文章