2016年7月19日星期二

CentOS 安装 Nginx 与 PHP(FastCGI)



安装 Nginx


Nginx 安装比较简单,可以到这里查看:

http://nginx.org/en/docs/install.html
https://www.nginx.com/resources/wiki/start/topics/tutorials/install/


安装 PHP


1.下载 PHP


到官方网站下载 PHP。网址 http://php-fpm.org/downloads/

2.解压 PHP


tar zxf php-x.x.x



3.编译 PHP (这里只简单设置支持 PHP-FPM 和 MySQL ),高级命令查看后文



cd ../php-x.x.x

./configure --enable-fpm --with-mysql 

make 

make install


4.复制配置文件到正确位置


cp php.ini-development /usr/local/php/php.ini 
cp /usr/local/etc/php-fpm.conf.default /usr/local/etc/php-fpm.conf 
cp sapi/fpm/php-fpm /usr/local/bin


5. 如果访问 Nginx 的文件不存在时,要阻止请求传递到 PHP-FPM 后端,防止任意脚本注入。


我们可以通过设置我们的php.ini文件中的 cgi.fix_pathinfo 语句为 0 来解决这个问题。

查找 php.ini:

vim /usr/local/php/php.ini


找到 cgi.fix_pathinfo 语句:

cgi.fix_pathinfo=0



在启动服务之前,php-fpm.conf 必须修改指定 PHP-FPM 服务必须作为用户 www-data 和 组 www-data 运行 :

vim /usr/local/etc/php-fpm.conf


找到下面的代码,修改成下面这样:

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group ; will be used.

user = www-data 
group = www-data



现在就能够启动 php-fpm 服务了:

/usr/local/bin/php-fpm



Nginx 配置支持PHP应用程序:

vim /usr/local/nginx/conf/nginx.conf


找到类似以下代码,修改如下,配置支持 .php 文件:

location / {
 root html;
 index index.php index.html index.htm;
}


下一步骤是确保 PHP 文件传递到 PHP-FPM 后端. 找到关于 PHP location 指令,输入以下内容:

location ~* \.php$ { 
 fastcgi_index index.php; 
 fastcgi_pass 127.0.0.1:9000; 
 include fastcgi_params; 
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
 fastcgi_param SCRIPT_NAME $fastcgi_script_name; 
}


重启 Nginx.

sudo /usr/local/nginx/sbin/nginx -s stop 
sudo /usr/local/nginx/sbin/nginx



创建测试文件
rm /usr/local/nginx/html/index.html
echo "<?php phpinfo(); ?>" >> /usr/local/nginx/html/index.php


在浏览器中打开 http://localhost 。 phpinfo() 就能够显示了。



编译 PHP 高级命令

./configure --prefix=/usr/local/php  --enable-fpm --with-mcrypt --enable-mbstring --with-curl --enable-inline-optimization --with-bz2  --with-zlib --enable-sockets --enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex --with-mhash --enable-zip --with-pcre-regex --with-mysql --with-mysqli --with-gd --with-jpeg-dir --with-openssl --enable-xml --with-png-dir --disable-rpath --with-freetype-di


参考:http://ixdba.blog.51cto.com/2895551/806622

上一篇:Nginx 与 PHP-FPM 运行原理

2016年6月29日星期三

Nginx 与 PHP-FPM 运行原理

一、什么是 FastCGI

FastCGI是一个可伸缩地、高速地在HTTP server和动态脚本语言间通信的接口。多数流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等,同时,FastCGI也被许多脚本语言所支持,其中就有PHP。
FastCGI是从CGI发展改进而来的。传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后结果被返回给HTTP服务器。这在处理高并发访问时,几乎是不可用的。另外传统的CGI接口方式安全性也很差,现在已经很少被使用了。
FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。

二、Nginx + FastCGI 运行原理

Nginx 不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过 FastCGI 接口来调用。FastCGI 接口在 Linux 下是 socket,(这个 socket 可以是文件 socket,也可以是 ip socket)。为了调用 CGI 程序,还需要一个 FastCGI 的 wrapper(wrapper可以理解为用于启动另一个程序的程序),这个 wrapper 绑定在某个固定 socket 上,如端口或者文件 socket。当 Nginx 将 CGI 请求发送给这个 socket 的时候,通过 FastCGI 接口,wrapper 接纳到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper 再将返回的数据通过 FastCGI 接口,沿着固定的 socket 传递给 Nginx;最后,Nginx 将返回的数据发送给客户端,这就是 Nginx + FastCGI 的整个运作过程。详细的过程,如图1所示。



三、Nginx 与 PHP-FPM

前面介绍过,FastCGI 接口方式在脚本解析服务器上启动一个或者多个守护进程对动态脚本进行解析,这些进程就是 FastCGI 进程管理器,或者称之为 FastCGI 引擎, PHP-FPM 就是支持 PHP 的进程管理器。

Nginx 是个轻量级的 HTTP server,必须借助第三方的 FastCGI 处理器才可以对 PHP 进行解析。
PHP-FPM 是一个第三方的 FastCGI 进程管理器,它是作为 PHP 的一个补丁来开发的,在安装的时候也需要和 PHP 源码一起编译,也就是说 PHP-FPM 被编译到 PHP 内核中,在处理性能方面更加优秀;因此,推荐 Nginx+PHP/PHP-FPM 这个组合对 PHP 进行解析(在 ./configure 的时候带 -enable-fpm 参数即可开启PHP-FPM)。

FastCGI 的主要优点是把动态语言和 HTTP Server 分离开来,所以 Nginx 与 PHP/PHP-FPM 经常被部署在不同的服务器上,以分担前端 Nginx 服务器的压力,使 Nginx 专一处理静态请求和转发动态请求,而 PHP/PHP-FPM 服务器专一解析 PHP 动态请求。

下一篇:CentOS 安装 Nginx 与 PHP(FastCGI)

Linux ls 命令出现 Input/output error 错误的问题

今天 Linux 机器忽然发现一个问题:目录访问不了了,运行 ls 命令出现下面的错误。



运行 df -h 命令来查看系统硬盘情况。




然后用 fdisk -h 或者 lsblk 去看机器有哪些硬盘。发现只有sdb 和 sdc。然后卸载,重新把正确的盘挂载到 /webdata 上:

umount /dev/sda

mount /dev/sdc  /webdata


最后就可以访问了。

2016年6月14日星期二

PHP 设置 HTTP 头信息导出 Excel 报表


不需要用到 fputcsv 函数来生成报表。只需设置相应的格式和HTTP头信息,就能够生成报表了。附上代码:

<?php

header("Content-type: application/vnd.ms-excel; charset=utf-8");
header("Content-Disposition: attachment; filename=excel.xls");

$data  = "分类销售统计\t\n";
$data .= "排名\t产品大类\t销售额(万)\t销售占比\t单品数量\n";

if (EC_CHARSET == 'utf-8')
{
      echo ecs_iconv(EC_CHARSET, 'GB2312', $data);
}
else
{
      echo $data;
}
?>

说明:字符转换这一步骤根据实际需要可以省略。

2016年5月31日星期二

用 Media Queries 设计移动网页端

今天来通过Media Queries样式模块,可以实现根据移动设备的屏幕大小,定制网站页面的不同布局效果。它的优点是开发者只需要实现一套页面,就能够在所有平台的浏览器下访问网站的不同效果。


用 viewport 设置适应移动设备屏幕大小

1.什么是 viewport

Apple 为了解决移动版 Safari 的屏幕分辨率大小问题,专门定义了 viewport 虚拟窗口。它的主要作用是允许开发者创建一个虚拟的窗口(viewport),并自定义其窗口的大小或缩放功能。

如果开发者没有定义这个虚拟窗口,移动版 Safari 的虚拟窗口默认大小为 980 像素。现在,除了Safari浏览器外,其他浏览器也支持 viewport 虚拟窗口。但是,不同的浏览器对viewport窗口的默认大小支持都不一致。默认值分别如下:

— Android Browser 浏览器的默认值是 800 像素;

— IE 浏览器的默认值是 974 像素;

— Opera 浏览器的默认值是 850 像素。

2.如何使用 viewport

viewport虚拟窗口是在meta元素中定义的,其主要作用是设置Web页面适应移动设备的屏幕大小。

如以下代码:

<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0" />

该代码的主要作用是自定义虚拟窗口,并指定虚拟窗口width宽度为device-width,初始缩放比例大小为1倍,同时不允许用户使用手动缩放功能。

在上面的代码中,我们使用了一个特别的名字:device-width。自iPhone面世以来,其屏幕的分辨率一致维持在 320´480。由于 Apple 在加入 viewport 时,基本上使用 width=device-width 的表达方式来表示 iPhone 屏幕的实际分辨率大小的宽度,比如 width=320。因此,其他浏览器厂商在实现其 viewport 的时候,也兼容了 device-width 这样的特性。

代码中的 content 属性内共定义三种参数。实际上 content 属性允许设置6种不同的参数,分别如下:


— width 指定虚拟窗口的屏幕宽度大小。

— height 指定虚拟窗口的屏幕高度大小。

— initial-scale 指定初始缩放比例。

— maximum-scale 指定允许用户缩放的最大比例。

— minimum-scale 指定允许用户缩放的最小比例。

— user-scalable 指定是否允许手动缩放。


Media Queries如何工作


1、定义当前屏幕可视区域的宽度最大值是600像素


<link href="small.css" rel="stylesheet" media="screen and(max-width:600px)"/>
那么 small.css 怎样写的呢


@media screen and (max-width:600px) { .demo { background-color:red; } }


2、定义当前屏幕可视区域的宽度长度在600到900像素之间

<link href="small.css" rel="stylesheet" media="screen and(min-width:600px) and(max-width:900px)"/>

@media screen and (min-width:600px) and (max-width:900px) { .demo { background-color: red; } }


3、当移动屏幕处于纵向(portrait)模式下时,应用portrait样式文件,当移动设备处于横向(landscape)模式下,应用landscape样式文件


<link href="protrait.css" rel="stylesheet" media="all and(orientation:portrait)"/> <link href="landscape.css" rel="stylesheet" media="all and(orientation:landscape)"/>

Media Queries语法总结

语法格式如下图所示:



1、使用 Media Queries 样式模块时都必须以“@media”方式开头

2、media_query 表示查询关键定,比如说not only and 等等
  • not 表示对后面的样式表达式执行取反操作 
  • only 让不支持 Media Queries 的设备但能读取 Media Type 类型的浏览器忽略这个样式,对于支持 Media Queries 的移动设备来说,如果存在 only 关键字,移动设备的浏览器会忽略only关键字并直接根据页面的表达式应用样式 文件 

3、media_type 指定设备类型(也称媒体类型)

4、media_feature 定义 css 中的设备特征  

media_type设备类型一览表




media_feature设备特征一览表

大部分设备特征都允许接受min/max的前缀

2016年5月30日星期一

用 PHP 自带函数 fputcsv 和 fgetcsv 来导出报表和导入报表

PHP 自带函数 fputcsv 可以实现打印报表(Excel)功能。如果你的对报表格式要求不是很高,那么 fputcsv 是很好的选择。它执行效率高,不需要第三方库,用起来很方便。

一、用 fputcsv 导出报表


<?php
$list = array
(
"George,John,Thomas,USA",
"James,Adrew,Martin,USA",
);

$file = fopen("contacts.csv","w");

foreach ($list as $line)
{
  fputcsv($file,split(',',$line));
}

fclose($file);
?>


以上代码会在本地生成一个 csv 的文件,能够用 Excel 打开,是不是很简单呢。如果有中文,在 Linux 执行后,下载到本地打开会乱码,那么可以用 iconv 函数进行转换。


$list = array();
$tmp = "订单号,订单支付金额,幸运号码,用户名,用户类型,期别,号码产生时间,开奖时间,奖项标识,奖项,奖金,备注";
$list[] = iconv('UTF-8', 'GB2312//IGNORE',$tmp);   


直接把生成的 CSV 输出到浏览器

header ( 'Content-Disposition: attachment; filename=contacts.csv');//如果文件名是中文的, urlencode 之后在IE不会出现中文乱码
header ( 'Content-type: application/octet-stream' );
header ( 'Content-Length: '.filesize ('contacts.csv') );//文件的大小
readfile ($file_path);
exit ();  

二、用 fgetcsv 导入报表

用 fgetcsv 导入报表有一点需要注意的地方。就是必须把 EXCEL 文档转换成 CSV 格式。注意:不是简单的改后缀名。

<?php

$file = fopen("contacts.csv","r");

while(! feof($file))
  {
  print_r(fgetcsv($file));
  }

fclose($file);

?> 

2016年5月20日星期五

PHP Excel 出现 PHP Warning: ZipArchive::open() Unable to access php://output 的解决方案

本来服务器用PHP Excel 导出 excel 运行得好好的,忽然出现 PHP Warning: ZipArchive::open() Unable to access php://output 原因。



下载的文件,打开也出现这样的错误。



原来服务器 php.ini 的配置被改了。启用了安全模式,只要把安全模式关了就行。

; Safe Mode
; http://php.net/safe-mode
safe_mode = Off

; By default, Safe Mode does a UID compare check when
; opening files. If you want to relax this to a GID compare,
; then turn on safe_mode_gid.
; http://php.net/safe-mode-gid
safe_mode_gid = Off

2016年5月18日星期三

Android 调用微信登录出现 错误提示:{"errcode":40029,"errmsg":"invalid code"} 原因

在开发安卓应用微信登录时,安卓应用发起微信授权登录请求,微信用户允许授权安卓应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;

但是发现 https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code 返回这样的错误信息 返回 {"errcode":40029,"errmsg":"invalid code, hints: [ req_id: xxxx]"}



查阅相关资料,说是因这个code已经用过了,如果需要再次调用用户信息还要重新获取一次。

原来安卓默认设置超时时间是3秒,当超过3秒时,会重新发起请求。这就导致了 code 无效的原因。

2016年5月14日星期六

JavaScript 与 PHP 进行 RSA 加密解密实例

RSA 即“非对称加密算法”。它有3个特征: 
  1. 乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
  2. 甲方获取乙方的公钥,然后用它对信息加密。
  3. 乙方得到加密后的信息,用私钥解密。

在开发应用的时候,你可能会碰到这样的需求:密码不能够明文传输,并且你无法用 HTTPS 协议。这时就可以用到 RSA 来解决这个需求了。

以下是 JAVASCRIPT 调用 RSA 源码:

var public_key="00b0c2732193eebde5b2e278736a22977a5ee1bb99bea18c0681ad97484b4c7f681e963348eb80667b954534293b0a6cbe2f9651fc98c9ee833f343e719c97c670ead8bec704282f94d9873e083cfd41554f356f00aea38d2b07551733541b64790c2c8f400486fd662a3e95fd5edd2acf4d59ca97fad65cc59b8d10cbc5430c53";
var public_length="10001";

var rsa = new RSAKey();
rsa.setPublic(public_key, public_length); 
var password = rsa.encrypt(password);

我们可以通过浏览器开发人员工具查看密码已经加密。

 再来看 PHP 是如何调用 RSA 算法的。

<?php
require_once 'rsa.php';

function convert($hexString) {
 $hexLenght = strlen ( $hexString );
 // only hex numbers is allowed 
 if ($hexLenght % 2 != 0 || preg_match ( "/[^\da-fA-F]/", $hexString ))
  return false;
 $binString = '';
 for($x = 1; $x <= $hexLenght / 2; $x ++) {
  $binString .= chr ( hexdec ( substr ( $hexString, 2 * $x - 2, 2 ) ) );
 }
 
 return $binString;
}
/**
 * RSA 解密
 *
 */
function decryptPassword($password) {
 $modulus = '124124790696783899579957666732205416556275207289308772677367395397704314099727565633927507139389670490184904760526156031441045563225987129220634807383637837918320623518532877734472159024203477820731033762885040862183213160281165618500092483026873487507336293388981515466164416989192069833140532570993394388051.0000000000';
 $private = '59940207454900542501281722336097731406274284149290386158861762508911700758780200454438527029729836453810395133453343700246367853044479311924174899432036400630350527132581124575735909908195078492323048176864577497230467497768502277772070557874686662727818507841304646138785432507752788647631021854537869399041.0000000000';
 $public = "65537";
 $keylength = "1024";
 $encrypted = convert ( $password ); //hex data to bin data

 //php encrypt create  
 //$encrypted = rsa_encrypt("vzxcvz bdxf", $public, $modulus, $keylength);
 //$str= bin2hex($encrypted);//bin data to hex data 
 //$str = $_POST['ciphertext'];
 //echo $str."
";
 
 return rsa_decrypt ( $encrypted, $private, $modulus, $keylength );
}

?>
这样,就可以解密出明文的密码了。这里附上 demo,有兴趣的童鞋可以下载,在自己的服务器运行。https://yunpan.cn/cSfKMpfffVFzu  访问密码 1fe5

2016年5月12日星期四

ECSHOP 如何开发一个模块后台管理

就以在公司网站做的一个功能为例子:要与第三方平台进行积分迁移与兑换。此时需要增加一个后台管理功能:1)查看与搜索相关记录。2)添加与编辑相关记录。

当用 ECSHOP 添加一个后台功能时,会涉及到添加和修改一些文件。如下图,

说明:guatenghui 是系统 ECSHOP 的目录。rate_info_list.php,rate_list.htm,rate_info.htm 是新增主文件和模板。inc_menu.php,inc_priv.php 则是控制后台菜单和权限的文件。common.php,rate_info_list.php,priv_action.php 则是语言文件。






一、开发管理后台功能关键一步是添加菜单和权限

添加菜单主要在 admin\includes\inc_menu.php 文件中(图2)。菜单语言文件则在 languages\zh_cn\admin\common.php 中(图3)


图2


图3

这样后台导航栏就会增加一个主菜单以及3个子菜单。



添加权限主要在 admin\includes\inc_priv.php 文件中。数组的键要和 admin\includes\inc_menu.php 键相对应(图2)。



权限的值还需要插入表 ecs_admin_action 中。



最后再 languages\zh_cn\admin\priv_action.php 中添加语言描述。


这样,菜单和权限就添加完毕了。



二、PHP 文件验证权限。

    /* 权限判断,直接请求 */
    admin_priv('rate_info_manage');

    /* 权限判断,请求为 AJAX 时 */
    check_authz_json('rate_info_manage');

三、至于主文件和模板直接复制过来改改就可以了。

源码下载:https://yunpan.cn/cPaDHkUBhhJ3h  访问密码 2b4d

四、一些注意的地方。不要忘记记录操作日志。

    /* 如:记录管理员操作,删除会员帐号 */
    admin_log(addslashes($username), 'remove', 'users');

    /* 后台一些常用到函数。详细信息可以查 ECSHOP 源代码说明*/

    // 返回提示信息
    $lnk[] = array('text' => $_LANG['go_back'], 'href'=>'users.php?act=list');

    sys_msg($_LANG['no_select_user'], 0, $lnk);

    //AJAX 请求时,返回错误提示信息
    make_json_error($msg);
  
    //AJAX 请求时,返回查询结果
    make_json_result($smarty->fetch('rate_list.htm'), '',

        array('filter' => $rate_list['filter'], 'page_count' => $rate_list['page_count']));
   

2016年5月11日星期三

Linux 用 phpize 快速扩展php模块


一,phpize的好处


什么时候我们要用phpize呢?我们在安装php时:

# ./configure --prefix=/usr/local/php  --enable-fpm --enable-fastcgi --enable-ftp --with-mcrypt --enable-mbstring --with-curl --with-iconv --with-gettext --enable-inline-optimization --with-bz2  --with-zlib --enable-sockets --enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex --with-mhash --enable-zip --with-pcre-regex --with-mysql=/usr/local/mysql --with-mysqli --with-gd --with-jpeg-dir=/usr --with-png-dir=/usr --with-openssl --enable-xml --disable-rpath --with-freetype-dir=/usr

后面根的参数是我们要的模块,但是随着工作的需要,我们还要在加些模块,又不想重新编译php,这些我们就可以用phpize了。



二,安装php模块


下面我以mcrypt安装为例子

# cd /root/php-5.2.6/ext/mcrypt #ext目录下面放的是php的模块库

# /usr/local/php/bin/phpize


#确定 php-config 文件在不在,调用php-config,安装后 .so 文件会自动放到 extension_dir 里面

# ./configure --with-php-config=/usr/local/php/bin/php-config


# make

安装完后会有这样的东西



See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.


# make install

Installing shared extensions: /usr/lib64/php/modules/


三,查看.so文件,以及修改 php.ini


ls -l /usr/lib64/php/modules/


# vi /usr/local/php/lib/php.ini

extension = "mcrypt.so"


四,重起apache或者phpcgi或者其他



CentOS 用 phpize 安装 PHP 扩展出现 Can't find PHP headers in /usr/include/php 原因

因为要在 CentOS 用 PHP 操作 Oracle 数据库,要安装新的 PHP 扩展 oci8 。

关于安装 PHP 扩展,以前总以为要重新编译 PHP,今天查阅大量资料发现原来可以像apache模块一样动态扩展。今天就以 oci8 举例。

一、进入要安装的扩展的源码目录(没有就到官方下载源代码)

# cd /root/php-5.5.35/ext/oci8

运行 phpize ,如果不知道 phpize 在哪个目录,可以运行 # which phpize  命令





# /usr/bin/phpize   # 这一步可能会出现以下错误



按照字面的意思,可能是你没安装 php-devel 这个扩展包。phpize是用来扩展php扩展模块的,通过phpize可以建立php的外挂模块,phpize 是属于php-devel的内容,所以只要运行yum install php-devel 就行

# yum install php-devel   # 却出现以下提示



这说明仓库里默认的 phpize 和 PHP 版本不一致。从下面的命令可以看出:php-devel 版本是 5.3.3 。这就需要我们重新安装 phpize 。







安装与当前 PHP 版本一致的 php-devel 。PHP 版本可以通过 php -v 查看。



所以安装与当前系统 PHP 对应的 php-devel 就可以了。运行 yum install php55w-devel 出现以下信息,安装成功。


二、运行 /usr/bin/phpize 出现以下信息,说明可以了。




# ./configure --with-php-config=/usr/bin/php-config
# make 

# make install

安装完后会有这样的东西,Installing shared extensions: /usr/lib64/php/modules 。说明系统已经默认把 oci8.so 模块安装在 /usr/lib64/php/modules 目录中了。



三,修改php.ini

# vi /etc/php.ini


由于我的 CentOS 里 PHP 是以这种方式扩展模块。所以只需在 /etc/php.d 里面添加相应的文件就可以了。


关于PHP扩展,可以通过 phpinfo(); 来查看。



四、重启 Apache



Linux 系统 PHP 连接 Oracle 出现 ORA-24408: could not generate unique server group name 解决方法



在 Linux 服务器上出现 "ORA-24408: could not generate unique server group name" 错误, 相同的代码在本地 Windows 没有问题。Google了一下,找到解决方法:

/etc/sysconfig/network 有 "HOSTNAME=netdisk7" 记录(netdisk7是设置的主机名,如果不存在则需要添加),然后 在 /etc/hosts 中添加 127.0.0.1  netdisk7,两个Hostname一定要一致, 如果修改了/etc/sysconfig/network 则需要执行 service network restart 生效。

# vi /etc/sysconfig/network



# vi /etc/hosts



参考来源:http://www.cnblogs.com/enjoycode/p/3542739.html

http://blog.csdn.net/geniuslinchao/article/details/22662917

2016年5月10日星期二

Oracle 怎样一次插入多条记录

Oracle 一次性插入多条记录跟 MYSQL 有很大不同。MYSQL  是这样的,但在 Oracle 中行不同。

INSERT INTO Persons (LastName, Address) VALUES ('Wilson', 'Champs-Elysees'),('Gates', 'Champs-Elysees')

Oracle 可以使用虚拟表 dual 一次插入多条记录。dual 在Oracle里有一个很奇特的“表”。可以利用这个Dual来做文章。

首先,你知道 select '1' from dual 是啥结果吗? 对了,结果就是返回1。

其次,你知道
select '1' from dual
union all
select '2' from dual

是啥结果吗? 对鸟,结果是

1
2

那么,最关键的地方来了,

insert into 表名 (字段1)
select '1' from dual
union all
select '2' from dual

那么这一次就插入了两条数据。当然,如果全字段插入 那个(字段1)还可以省略掉。
下面一个具体例子:

insert into doc_data (code,id,value,state)
        select '13','川A','成都市公安局交通警察支队车辆管理所',0 from dual
union all select '13','川B','绵阳市公安局交通警察支队车辆管理所',0 from dual
union all select '13','川C','自贡市公安局交通警察支队车辆管理所',0 from dual
union all select '13','川D','攀枝花市公安局交通警察支队车辆管理所',0 from dual

参考:Oracle使用虚拟表dual一次插入多条记录

PHP 连接 Oracle 出现中文乱码问题

数据库用 oracle,当 PHP连接 Oracle 的时候,如果指定字符集,会出现中文乱码。

查PHP手册,oci_pconnect  的第四个参数为 charset,只需设置这参数即可。

首先获取 Oracle 的字符集,运行“SELECT * FROM V$NLS_PARAMETERS;”,变量NLS_CHARACTERSET对应的就是我们需要的字符集,比如我这里就是 “AL32UTF8”。所以,最终的PHP代码为:


$conn = oci_pconnect('scott','tiger',
 "(DEscriptION=(ADDRESS=(PROTOCOL =TCP)(HOST=192.168.0.1)(PORT = 1521))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME=jocsbk)))",
 'AL32UTF8');

由于本地的 PHP 文件统一用 utf-8 ,所以,直接输出就正常了。不用进行编码转换。

另外,据查询相关资料,如果你本地的文件跟连接 Oracle 的字符集不相同,还要进行编码转换


while ($dat = oci_fetch_row($cur)) {   
  print_r(iconv('gb2312', 'utf-8', $dat[0]));   
}  

//或者


while ($dat = oci_fetch_row($cur)) {   
  print_r(mb_convert_encoding($dat[0], 'utf-8', 'gbk'));   
}  

也有另外一种解决方式,但没试过。Oracle 可以按照 客户端指定的字符集 提供数据。也就是说,如果我本地PHP文件用UTF-8,那么,我在oci_connect的时候,直接指定utf-8就行了,连编码转换都省了。

$c1 = oci_connect("scott", "tiger", $db, 'UTF8');  

2016年5月7日星期六

文件上传 PHP 总是获取空值的原因

前不久在为公司的项目瓜藤网(http://www.guaten.com/)的后台作一个扩展的时候,商品属性可以上传图片。


发现后台 PHP 获取的文件总是空值,花了很长时间才发现是这个原因:



PHP 能否上传文件以及上传多少个文件,取决于两个值:file_uploads 和 max_file_uploads。

发现在 HTML 文档中 <input type="file"> 标签太多,超过了 php.ini  中的值 max_file_uploads 设置的最大值。只要把 max_file_uploads  调大就行了。


PHP 调用 Oracle 存储过程出现 not all variables bound 原因

今天发现使用 PHP 调用 Oracle 存储过程总是出现这样的一个错误。

ORA-01008: not all variables bound

后来折腾了很久,发现是变量名写错了。

<?php
$conn = oci_connect('SCOTT','TIGER') or die;// 建立连接 

if (!$conn) { 
 $e = oci_error(); 
 print htmlentities($e['message']); 
 exit; 
} 

$sql = 'BEGIN pack_gt_calc.Pro_gt_Confirm(:year, :week, :errno, :errmsg); END;'; // 查询语句 
$stid = oci_parse($conn, $sql); // 配置SQL语句,准备执行 
if (!$stid) { 
 $e = oci_error($conn); 
 print htmlentities($e['message']); 
 exit; 
}

//  Bind the input parameter
oci_bind_by_name($stid,':year',$year,32);

// Bind the input parameter
oci_bind_by_name($stid,':week',$week,32);

// Bind the output parameter
oci_bind_by_name($stid,':errno',$error,32);
// Bind the output parameter
oci_bind_by_name($stid,':ermsg',$errmsg,64);
// Assign a value to the input 

$year = '2016';

$week = '4';

$r = oci_execute($stid); // 执行SQL。OCI_DEFAULT表示不要自动commit 


if(!$r) { 
 $e = oci_error($stid); 
 echo htmlentities($e['message']); 
 exit; 
} 

echo "errmsg is : $error<br>";
echo "errmsg is : $errmsg<br>";

oci_close($conn); 

?>


参考资源:http://www.oracle.com/technetwork/cn/articles/fuecks-sps-082839-zhs.html

2016年4月29日星期五

PHP 无法开启 OCI8 扩展原因

今天刚好有个需求,要用 PHP 把数据写入远程 Oracle 数据库,所以要用到 OCI8 扩展。但总是无法开启,查阅了大量资料才知道原来是因为本地机器没安装 Oracle 数据库, 系统缺少Oracle的几个关键DLL造成的,可以通过安装Oracle Instant Client 来添加这些DLL。

Oracle Instant Client下载地址如下:

下载后,将其解压到 D:\Program Files\instantclient_11_2 (非固定位置),并将该路径加入到系统PATH环境变量的最前面。
然后重启一下Webserver,再查看phpinfo,可以OCI8模块信息了。

总结一下,PHP OCI8扩展的开启步骤:
(1)去掉php.ini中extension=php_oci8.dll前面的注释。

(2)解压 Oracle Instant Client,并将解压目录加入到系统PATH环境变量中。

(3)重启Webserver,使用phpinfo查看OCI8模块是否出现。



下面是Oracle官方的安装说明,很详细:
《nstalling PHP and the Oracle Instant Client for Linux and Windows

另外关于PHP操作Oracle的资料,这个感觉不错:

OCI8操作Oracle的PHP手册:

2016年4月27日星期三

PHP 获取远程图片(文件)并把它保存到本地

// 获取远程图片并把它保存到本地,确定您有把文件写入本地服务器的权限
// 变量说明:
// $url 是远程图片的完整URL地址,不能为空。
// $filename 是可选变量: 如果为空,本地文件名将基于时间和日期
// 自动生成.

function grab_image($url,$filename='') {
    if($url=='') {
       return false;
    }

    if($filename=='') {
        $ext = strrchr($url,".");
        if($ext!=".gif" && $ext!=".jpg" && $ext!=".png") {
           return false;
         }
        $filename = date("dMYHis").$ext;
    }
    ob_start();
    readfile($url);
    $img = ob_get_contents();
    ob_end_clean();

    $fp2=@fopen($filename, "a");
    fwrite($fp2,$img);
    fclose($fp2);

    return $filename;
}


远程获取文件原理与获取图片原理是类似的。这一步判断不要就可以了。

        if($ext!=".gif" && $ext!=".jpg" && $ext!=".png") {
           return false;

         }

2016年4月26日星期二

微信登录获取 openid 失败原因



今天再开发网站微信登录的时候,用 curl_init 无法获取 openid,代码如下

<?php
    $code = isset($_GET['code']) ? trim($_GET['code']) : '';
    $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.WX_APPID.'&secret='.WX_SECRET.'&code='.$code.'&grant_type=authorization_code';
    $ch = curl_init();
    curl_setopt ($ch, CURLOPT_URL, $url);
    curl_setopt ($ch, CURLOPT_HEADER, 0);// 显示返回的Header区域内容   
    curl_setopt ($ch, CURLOPT_TIMEOUT, 30);// 设置超时限制
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,10);// 链接超时限制
    curl_setopt ($ch, CURLOPT_HTTPHEADER,array('Accept-Encoding: gzip, deflate'));//设置 http 头信息
    curl_setopt ($ch, CURLOPT_ENCODING, 'gzip,deflate');//添加 gzip 解码的选项,即使网页没启用 gzip 也没关系 
    $content = curl_exec($ch);

?>


后来发现跟 https 有关,加上下面这两个选项就可以了

    curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST,0);
    curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER,0); 


由于 CURLOPT_SSL_VERIFYPEER 的预设值为 TRUE 是要验证伺服器凭证的,所以当拜访 https 网站时,若未做任何 SSL 相关设定,会出现以下错误。
Error Number: 60
Error Message: SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
如果只是要拜访 https 网站,但不会来回传递敏感信息,可以把 CURLOPT_SSL_VERIFYPEER 设定为 FALSE,代表可以盲目接受任何伺服器凭证。

而当 CURLOPT_SSL_VERIFYPEER 为 FALSE 时,其他诸如 CURLOPT_SSL_VERIFYHOST, CURLOPT_CAINFO, CURLOPT_CAPATH 等设定,都不具任何意义。