手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:PHP

为 Linux 和 Windows 安装 PHP 和 Oracle 10g Instant Client

这是一篇 很老的文章了,那时候,PDO应该还没有出来吧。不过,仍然可以作为参考。。这里是纯记录,做个笔记

备注:如果看完下文,你觉得还不够,那么,看看这个吧:http://wiki.oracle.com/page/PHP+Oracle+FAQ?t=anon


原文:http://www.oracle.com/technology/global/cn/pub/notes/technote_php_instant.html

Oracle 10g Instant Client(免费下载)是PHP 与远程 Oracle 数据库连接的最简单方式,它只需要安装三个库。

PHP 访问 Oracle 的当前 API 所使用的 Instant Client 库称作 OCI8.(此 C 接口的名称最早是在 Oracle8 中引入的。)PHP Oracle 8 函数 可以直接调用 Oracle 8.1.7、9.x 或 10.x,或者也可以为了方便起见,使用可选的抽象类,如 PEAR MDB2ADOdb

Instant Client 也可以使用老版本的 PHP“oracle”扩展,但它调用不赞成使用的 Oracle API。PHP 界或 Oracle 建议不要使用此扩展进行新的开发。

要在 Apache 上将 Instant Client 与 PHP 4 或 连用,请遵循以下步骤。需要一个现有的 Oracle 数据库;Instant Client 不提供 Oracle 数据库。通常情况下,此数据库将位于其他计算机上。如果数据库位于本地,则 Oracle 组件一般早已可用,从而不需要 Instant Client。

软件需求:

软件 附注
Oracle Instant Client 下载“Instant Client Package - Basic”。在 Linux 上,还应下载“Instant Client Package - SDK”。
Apache HTTPD Server PHP 界仍推荐 Apache 1.3
PHP — PHP 超文本处理器 4.3 版或更高版本

在 Windows 上启用 PHP OCI8 扩展

Instant Client 二进制文件是 PHP 的 Windows 预构建二进制文件的补充。

  1. 下载 PHP 二进制压缩文件(不是安装程序版本)和 Apache。按照 PHP 手册中的 Windows 系统上的安装安装它们。OTN 的开放源代码开发人员中心包含有用背景资料的链接,如“在 Windows 2000/XP 上安装 Oracle、PHP 和 Apache”,它介绍了如何安装传统、完整的 Oracle 10g 版本(Instant Client 不需要此版本)。

    继续操作之前检查 PHP 是否正常运行。此阶段未启用 Oracle 支持。

  2. 从 OTN 的 Instant Client 页面下载用于 Windows 的 Instant Client Basic 程序包。此压缩文件的大小大约为 30MB。

  3. 创建一个子目录(例如,c:\instantclient10_1),然后从压缩文件中复制以下库:

    • oraociei10.dll
    • orannzsbb10.dll
    • oci.dll

    这三个文件的总大小大约为 80MB。

    要使用 PHP 老版本的“oracle”扩展(在 php.ini 中使用“extension=php_oracle.dll”启用),则复制 ociw32.dll 而非 oci.dll。

  4. 编辑此环境,将 c:\instantclient10_1 添加到 PATH 中(位于其他 Oracle 目录之前)。

    例如,在 Windows 2000 上,依次单击“开始”->“设置”->“控制面板”->“系统”->“高级”->“环境变量”,编辑系统变量列表中的 PATH。

    如果使用了 tnsnames.ora 文件定义 Oracle Net 服务名称,则将 tnsnames.ora 复制到 c:\instantclient10_1,并将用户环境变量 TNS_ADMIN 设置为 c:\instantclient10_1。也可以在用户环境变量 LOCAL 中定义默认的服务名称。

    设置必要的 Oracle 全球化语言环境变量,如 NLS_LANG。如果没有设置,则使用默认的本地环境。有关更多详细信息,请参见 Oracle PHP 应用程序全球化概述

    无需设置不必要的 Oracle 变量,如 ORACLE_HOME 和 ORACLE_SID。

  5. 编辑 php.ini,并不要将 OCI8 扩展设为注释:

    extension=php_oci8.dll

    将 extension_dir 指令设置为完整的 PHP 扩展 DLL 路径。在 PHP 4 中,DLL 位于 PHP 软件的“extensions”子目录中。在 PHP 5 中,它们位于“ext”中。

  6. 重新启动 Apache。

要检查是否配置了扩展,请在 web 服务器可以读取的地方创建一个简单的 PHP 脚本。

<?php 
phpinfo();
?>

使用“http://”URL 将此脚本加载到浏览器中。浏览器页面应包含一个显示“OCI8 Support enabled”的“oci8”部分。

在 Linux 上启用 PHP OCI8 扩展

要在 Linux 上添加 Oracle 连接,需要重新编译 PHP。

开放源代码开发人员中心包含有用背景资料的链接,如在 Linux 上安装 Oracle、PHP 和 Apache,它介绍了如何安装传统、完整的 Oracle 10g 版本(Instant Client 不需要此版本)。

  1. 下载并安装 Apache。例如,在您的主目录中安装它:
    cd apache_1.3.31
    ./configure --enable-module=so --prefix=$HOME/apache --with-port=8888
    make
    make install

    编辑 $HOME/apache/conf/httpd.conf 并添加:

    AddType application/x-httpd-php .php
    AddType application/x-httpd-php-source .phps
  2. 下载并解压缩 PHP。

  3. 从 OTN 上的 Instant Client 页面下载 Basic 和 SDK Instant Client 程序包。这两个 RPM 的总大小大约为 30MB。

  4. 以 root 用户的身份安装 RPM。

    rpm -Uvh oracle-instantclient-basic-10.1.0.3-1.i386.rpm
    rpm -Uvh oracle-instantclient-devel-10.1.0.3-1.i386.rpm

    第一个 RPM 将 Oracle 库置于 /usr/lib/oracle/10.1.0.3/client/lib 中,第二个 RPM 在 /usr/include/oracle/10.1.0.3/client 中创建头 (header)。

  5. 备份此补丁,然后将它应用于 PHP 的 ext/oci8/config.m4。该补丁的行号是基于 PHP 4.3.9 的。如果已修复了 PHP 错误 31084(很有可能已在 PHP 4.3.11 和 5.0.4 中修复),则不需要此补丁。

    如果使用的是 PHP 4.3.9 或 4.3.10,则可以将此补丁保存到一个文件中(如 php_oci8ic_buildpatch),然后使用以下命令安装它:

    patch -u config.m4 php_oci8ic_buildpatch

    此补丁创建一个新的 PHP 配置参数:--with-oci8-instant-client[=DIR].在 Linux 上,默认情况下,它使用从 RPM 中安装的最新版本的 Instant Client。可以指定 Oracle 库所在的目录来使用其他版本。无论在哪种情况下,都将自动使用正确的 SDK 头。

    新参数与现有的 --with-oci8 参数互斥。

    例如:在非 Linux 平台上,将 Instant Client 程序包解压缩到您所选择的目录中。--with-oci8-instant-client 参数将需要明确指定此目录;例如,--with-oci8-instant-client=/home/instantclient10_1。应将 Instant Client SDK 解压缩到与基本程序包相同的目录中,以便修改后的配置脚本可以找到头文件的子目录。

  6. 在顶层 PHP 目录中重新构建“configure”脚本。
    cd php-4.3.9
    rm -rf autom4te.cache config.cache
    ./buildconf --force
  7. 使用新选项运行 configure。此示例使用安装在主目录中的 Apache。

    ./configure \
    --with-oci8-instant-client \
    --prefix=$HOME/php --with-apxs=$HOME/apache/bin/apxs \
    --enable-sigchild --with-config-file-path=$HOME/apache/conf
  8. 重建 PHP。

    make
    make install
  9. 将 PHP 配置复制到 --with-config-file-path 指定的位置

    cp php.ini-recommended $HOME/apache/conf/php.ini
  10. 将 LD_LIBRARY_PATH 设置为 /usr/lib/oracle/10.1.0.3/client/lib 并重新启动 Apache。

    如果使用了 tnsnames.ora 文件定义 Oracle Net 服务名称,则将 TNS_ADMIN 设置为包含此文件的目录。

    启动 Apache 之前应设置所有 Oracle 环境变量。以下脚本可以帮助完成此操作:

    #!/bin/sh

    APACHEHOME=/home/apache

    LD_LIBRARY_PATH=/usr/lib/oracle/10.1.0.3/client/lib:${LD_LIBRARY_PATH}
    TNS_ADMIN=/home
    export LD_LIBRARY_PATH TNS_ADMIN

    echo Starting Apache
    $APACHEHOME/apachectl start

要确认是否配置了扩展,请在 web 服务器可以读取的地方创建一个简单的 PHP 脚本。

<?php 
phpinfo();
?>

使用类似“http://localhost:8888/<path>/phpinfo.php”的 URL 将此脚本加载到浏览器中。浏览器页面应包含一个显示“OCI8 Support enabled”的“oci8”部分。

连接到 Oracle

Oracle 连接信息被传递给 OCILogon() 来创建连接。与 Instant Client 关联的工具通常“远离”任何数据库服务器,因此必须将 Oracle Net 连接标识符与用户名和口令一起使用。对于已建立的 Oracle 数据库,连接信息有可能是众所周知的。对于新系统,此信息由 Oracle 安装程序在安装数据库时提供。此安装程序应配置了 Oracle Net 和创建了一个服务名称。

在新数据库中,可能需要将演示模式(如 HR 用户)解除锁定并向其提供口令。也可通过在 SQL*Plus 中以 SYSTEM 用户身份连接并执行以下语句来完成此操作:

ALTER USER 用户名 IDENTIFIED BY 新口令 ACCOUNT UNLOCK;

将连接信息传递给 PHP 有多种方法。第一个示例使用 Oracle 10g的 Easy Connect 语法连接到 在 mymachine 上运行的 MYDB 数据库服务中的 HR 模式。不需要 tnsnames.ora 或其他 Oracle Network 文件:

$c = OCILogon('hr', 'hr_password', '//mymachine.mydomain/MYDB');

有关 Easy Connect 的语法,请参见 Oracle 的使用 Easy Connect 命名方法文档。

或者,如果 /home/tnsnames.ora 包含:

MYDB =
(DESCRIPTION=
(ADDRESS = (PROTOCOL = TCP)(HOST = mymachine.mydomain)(PORT = 1521))
(CONNECT_DATA=
(SERVER = DEDICATED)
(SERVICE_NAME = MYDB)
)
)

且 TNS_ADMIN 环境变量设置为 /home(在启动 Apache 之前),则连接字符串可以为:

$c = OCILogon('hr', 'hr_password', 'MYDB');

如果环境变量 LOCAL(在 Windows 上)或 TWO_TASK (在 Linux 上)设置为 MYDB,则可以使用以下代码生成与 MYDB 连接:

$c = OCILogon('hr', 'hr_password');
使用 Oracle

当基本连接可以使用时,试着运行一个简单的脚本 testoci.php。根据您的数据库修改该连接的详细信息并在浏览器中加载它。此示例列出了用户 HR 拥有的所有表:

<?php 

$conn = OCILogon("hr", "hr_password", '//mymachine.mydomain:port/MYDB);

$query = 'select table_name from user_tables';

$stid = OCIParse($conn, $query);
OCIExecute($stid, OCI_DEFAULT);
while ($succ = OCIFetchInto($stid, $row)) {
foreach ($row as $item) {
echo $item." ";
}
echo "<br>\n";
}

OCILogoff($conn);

?>
故障诊断

Oracle PHP 故障诊断常见问题解答包含有关连接 Oracle 的有用信息。

可以从 Instant Client 页面下载 Oracle 的 SQL*Plus 命令行工具来帮助解决环境问题和连接问题。另请参见 SQL*Plus Instant Client 版本说明

检查 SQL*Plus 使用的环境是否与 phpinfo.php 显示的环境相同。

Windows 帮助

如果 phpinfo.php 脚本没有生成显示“OCI8 Support enabled”的“oci8”部分,则确认在 php.ini 中没有将“extension=php_oci8.dll”设为注释。

如果 PATH 设置错误,或找不到 Oracle 库,则启动 Apache 将显示警告:“在指定的路径中找不到动态链接库 OCI.dll。”phpinfo() 页面的 Environment 部分将显示 PATH 的值以及 PHP 实际使用的 Oracle 变量。

如果 php.ini 的 extension_dir 指令不正确,则在启动 Apache 将显示警告:“PHP 启动:无法加载动态库 php_oci8.dll。”

Linux 帮助

仔细检查是否正确修复了 config.m4。如果“configure”失败,则检查 config.log 文件。还原 config.m4,删除缓存文件,运行 ./buildconf --force and configure,验证问题是否与所做的更改相关。

确保“configure”上的时间戳是当前的。删除所有缓存文件,并在必要时重建它。

在启动 Apache 的 shell 中设置所有必要的 Oracle 环境变量。

结论

希望本文对您能有所帮助。您可以在 OTN Instant ClientPHP 论坛上发表问题和建议。

Tags: oracle

简单的处理thunder,flashget,qqdl的加密下载字符串

其实这些东西都是根据网上的资料来解决的。
那些下载字符串,在去除协议后,都是采用BASE64加密过,所以,先解密一下,再处理,就很方便了。

其中,迅雷是在解密后的字符串两头加了“AA”和“ZZ”两个字符串
flashget则是加了[FLASHGET]标签
QQ则最简单,啥也没加,解密后就能用。

flashget在处理前,需要先把&以后的字符串全部清空再作Base64的解密转换。

不多说,源码如下:

PHP代码
  1. function decode ( $string )  
  2. {  
  3.     $exp = explode"://"$string );  
  4.     $type = strToLower$exp[0] );  
  5.     if ( $type == 'thunder' ){  
  6.         return str_replace(array("AA","ZZ"),"",base64_decode$exp[1] ));  
  7.     }else if ( $type == 'flashget' ){  
  8.         $exp[1] = subStr$exp[1], 0 , strPos$exp[1], '&' ) );  
  9.         return str_ireplace("[flashget]","",base64_decode$exp[1] ));  
  10.     }else if ( $type == 'qqdl' ){  
  11.         return base64_decode$exp[1] );  
  12.     }  
  13. }  

关于base64

以前也曾经转载过关于BASE64方面的文章,那时候仅仅介绍了原理啥的。这回我找来的内容是如何实现的。。。

通过google找来了javaeye上的文章,他写了转载自xxx,进入xxx的页面,他告诉我转载自yyy每个人在转载的时候都去掉了一些内容。基于这样的现状,我。。。

不想转载了,贴出几个地址,自己看吧。

javaeye:http://chmod777.javaeye.com/blog/320301

xxx:http://www.cnblogs.com/yiki/archive/2009/01/18/1377828.html

yyy:http://www.cnblogs.com/reonlyrun/archive/2006/12/29/640991.html

这些实现在PHPer看来都是学习的经验,但phper根本不需要进行这些,因为php自带了base64_encode,base64_decode函数。

我要说的是,如何将加密的后的字符串在URL里传递,众所周知,base64中有三个特殊字符:"/,+,=",其中,=是补位码,/和+的标准字符,但/和=在URL里有着特定的意义,如果放到URL里,可能会被当成其他功能进行处理 。

于是,写了一个小函数进行了转换:

PHP代码
  1. function exchange ( $string , $reverse = false )  
  2. {  
  3.     if ( $reverse === false ){  
  4.         return str_replacearray("/","+","="), array(":","|",";"), $string );  
  5.     }else{  
  6.         return str_replacearray(":","|",";"), array("/","+","="), $string );  
  7.     }  
  8. }  
其实功能很简单,无非就是把这三个有特殊意义的字符转换成在URL里不被解析的三个字符,只要不和base64所规定的字符相关,也不是URL处理中的特殊字符,这三个字符你可以替换成你平时喜欢用的字符。。。

彻底杜绝PHP的session cookie错误

这种方式有点另类,但确实是一种解决的方案之一。而且ob的方式还可以用来开启gzip。呵呵

原文地址:http://www.cnblogs.com/webnet/archive/2009/05/22/1486939.html
内容:

本文讨论的是如何彻底杜绝warning: Cannot add header information - headers already sent in......  这种令人莫明其妙的的错误。

只要你写过PHP代码,相信都遇上过这个大多时候都令人莫明其妙的warning吧..今天我们就来搞定它...............

看了PHP手册,回答如下:

消息“Warning: Cannot send session cookie - headers already sent。。。”或者“Cannot add header information - headers already sent。。。”。

函数 header(),setcookie() 和 session 函数需要在输出流中增加头信息。但是头信息只能在其它任何输出内容之前发送。在使用这些函数前不能有任何(如 HTML)的输出。函数 headers_sent() 能够检查您的脚本是否已经发送了头信息。请参阅“输出控制函数”。

意思是:不要在使用上面的函数前有任何文字,空行,回车,空格等。但。。。问题是,这答案并不令人满意。因为往往程序在其他PHP环境下运行却正常。
 

首先:这错误是怎么产生的呢?让我们来看看PHP是如何处理HTTP header输出和主体输出的。

PHP脚本开始执行时,它可以同时发送header(标题)信息和主体信息。 Header信息(来自 header() 或 SetCookie() 函数)并不会立即发送,相反,它被保存到一个列表中。 这样就可以允许你修改标题信息,包括缺省的标题(例如 Content-Type 标题)。但是,一旦脚本发送了任何非标题的输出(例如,使用 HTML 或 print() 调用),那么PHP就必须先发送完所有的Header,然后终止 HTTP header。而后继续发送主体数据。从这时开始,任何添加或修改Header信息的试图都是不允许的,并会发送上述的错误消息之一。

好!那我们来解决它:

笨方法:把错误警告全不显示!
掩耳盗铃之计,具体方法就不说了 ^_^#

解决方案:

1)适用于有权限编辑PHP。INI的人

打开php。ini文件(你应试比我清楚你的php。ini在哪里),找到

output_buffering =改为on或者任何数字。如果是IIS6,请一定改为ON,不然你的PHP效率会奇慢。

2)使用虚拟主机,不能编辑PHP。INI,怎么办?

简单:

在你的空间根目录下建立一个。htaccess文件,内容如下:

AllowOverride All
PHP_FLAG output_buffering On

不幸的情况是:还是不行?全部网页都不能显示啦?

那么,你可以打电话骂一通空间商,然后让他给你把apache的。htaccess AllowOverride打开

3)在PHP文件里解决

ob_start()
启用output buffering机制。 Output buffering支持多层次 -- 例如,可以多次调用 ob_start() 函数。

ob_end_flush()
发送output buffer(输出缓冲)并禁用output buffering机制。

ob_end_clean()
清除output buffer但不发送,并禁用output buffering。

ob_get_contents()
将当前的output buffer返回成一个字符串。允许你处理脚本发出的任何输出。

原理:

output_buffering被启用时,在脚本发送输出时,PHP并不发送HTTP header。相反,它将此输出通过管道(pipe)输入到动态增加的缓存中(只能在PHP 4。0中使用,它具有中央化的输出机制)。你仍然可以修改/添加header,或者设置cookie,因为header实际上并没有发送。当全部脚本终止 时,PHP将自动发送HTTP header到浏览器,然后再发送输出缓冲中的内容。

Tags: session, cookie

“同名Cookie”的分析

原文基于.net,不过,我想PHP也差不多。而且这种问题很常见。。。

原文地址:http://www.cnblogs.com/flashlm/archive/2009/05/17/theSameNameCookie.html
内容:
了解Cookie的同学应该知道,浏览器客户端是以domain,path,name作为Cookie的唯一标识的,只要Name、Domain、Path中的任何一项不同,Cookie就是不能同的。由此便产生了同名Cookie。

例如有四个cookie如下:
d=1; expires=Sat, 23 May 2009 03:48:22 GMT; path=/; domain=.dny.com
d=2; expires=Sat, 23 May 2009 03:48:46 GMT; path=/; domain=.test.dny.com
d=3; expires=Sat, 23 May 2009 03:48:46 GMT; path=/test/; domain=.dny.com
d=4; expires=Sat, 23 May 2009 03:48:46 GMT; path=/test/; domain=.test.dny.com
他们是可以共存的。

了解Cookie的同学也应该知道,cookie的domain、path在服务器端都是只写的,也就是说在服务器端不能读取到任何一个Cookie的domain或者path值,只能读取到name和value。那么问题便产生了,假设上面的四个Cookie同时存在,那么服务器端读取到的name为“d”的cookie到底会是哪个值呢?

经过我的测试,结果是这样的,如果客户端浏览器发送了多个同名的 cookie,那么 Request.Cookie 将返回其中最符合(符合条件且范围最小)当前domain、path的一个

例如,还是上面四个cookie,我通过下面这些地址去获取Request.Cookie["d“],值是不同的:
http://test.dny.com/test/cookies.aspx    4
http://dny.com/test/cookies.aspx        3
http://test.dny.com/cookies.aspx        2
http://dny.com/cookies.aspx        1

而实际上,服务器上用Request.Cookies.Count可以知道,得到的确实是有4个Cookie。

以上内容欢迎更加深入讨论。

--EOF--


我在想,由于客户端保存cookie是有长度限制的,象上面这四个COOKIE,如果在客户端保存的话,也应该是存为两个文件,一个是test.dny.com,一个是dny.com,那么path,又是怎么处理 的呢?偷懒,没做试验。。。。。。

 

Tags: cookie