sh脚本,多目录git更新

git更新多个项目
如 a.xxtime.com, b.xxtime.com, c.xxtime.com

#!/bin/bash

data_path='/data/www/'
search='xxtime.com'

for file in ./*
do
    #if test -f $file
    #then
    #    echo $file 是文件
    #fi

    if test -d $file
    then
        #echo $file 是目录
        result=$(echo $file | grep "${search}")
        if [[ "$result" != "" ]]
        then
                echo ${data_path}${file##*/}
                cd ${data_path}${file##*/}
                git pull origin master
                cd ${data_path}
        fi
    fi
done
exit

ejabberd 管理,添加管理员登陆

安装好ejabberd后

修改管理员密码:
ejabberdctl register admin localhost password

给管理员赋予权限:
编辑配置文件 /usr/local/ejabberd/etc/ejabberd/ejabberd.yml
在97行左右,修改为

hosts:
  - "xxtime.com"

在400行左右,修改为

###.   ====================
###'   ACCESS CONTROL LISTS
acl:
  ## 
  ## The 'admin' ACL grants administrative privileges to XMPP accounts.
  ## You can put here as many accounts as you want.
  ## 
  admin:
    user:
      - "admin": "xxtime.com"
  ##     - "ermine": "example.org"
  ## 
  ## Blocked users
  ## 
  ## blocked:
  ##   user:
  ##     - "baduser": "example.org"
  ##     - "test"

重启

ejabberdctl restart

登陆管理后台:
http://localhost:5280/admin
根据自己设置输入用户名和密码
用户名:admin@xxtime.com
密码:123456

参考文献:
https://www.digitalocean.com/community/tutorials/how-to-install-ejabberd-xmpp-server-on-ubuntu
http://coderplay.iteye.com/blog/99893

SIP vs XMPP

SIP vs XMPP (Jabber)

SIP and XMPP are application layer protocols mostly used to send voice or IM over Internet. SIP is defined by RFC 3621 and XMPP is defined in RFC 3920. Basically XMPP is evolved from IM and Presence, whereas SIP evolved from Voice and Video over IP. XMPP added an extension called Jingle for session negotiation and SIP added an extension called SIMPLE to support IM and Presence.

SIP和XMPP都是应用层的协议,主要用来在互联网上发送语音和即时通信IM。RFC 3521定义了SIP,RFC3920定义了XMPP。XMPP来自即时通信系统,而SIP类似语音和视频通信。XMPP增加了Jingle扩展协议来支持面向连接的业务,如语音和视频;而SIP增加了SIMPLE协议来支持即时通信业务。

SIP (Session Initiation Protocol)

Session Initiation Protocol (SIP) is an application layer protocol used to establish, modify and terminate multimedia sessions such as VoIP Calls. SIP also can invite new sessions to existing sessions such as multicast conferences. Basically it’s referred as signalling protocol in VoIP environment that can handle call establishment, call control and call termination and generating CDR (Call Detail Record) for billing purposes.

SIP是应用层的协议,用来建立、改变和终结多媒体连接,如语音呼叫。SIP也可以在已经存在的呼叫上增加新的呼叫,实现多方会议。本质上来讲,SIP被称之为VoIP的信令协议,他可以处理呼叫的建立,呼叫的控制和呼叫的终结,并且产生CDR用来计费.

XMPP (Extensible Messaging Presence Protocol)

XMPP is an open Extensible Markup Language (XML) protocol for real time messaging, presence and request response services. Originally it was developed by Jabber open source community in 1999. In 2002 the XMPP working group developed adaptation of Jabber Protocol that is suitable for IM (Instant Messaging).

XMPP是开放的XML协议,用来实现实时消息传递、呈现和请求/响应业务。起初,他由Jabber开源社区开发。2002年,XMPP工作组将Jabber开发成支持即时通信的协议。

Difference Between SIP and XMPP

We just can’t compare SIP and XMPP because both serve different purposes like session establishment and structured data exchange respectively. But introduction SIMPLE and Jingle introduces some similar functionalities.

  我们不能简单对SIP和XMPP进行对比,因为两者服务与完全不同的目标,一个服务于连接的建立,一个服务于结构化的数据交换。但是SIP增加SIMPLE和XMPP增加Jingle后,两者开始变得类似了。

(1) SIP provides session establishment, modify and termination but XMPP provides streaming pipe for structured data exchange between group of clients.

SIP提供连接的建立、改变和终结,而XMPP在客户组内部提供流管道,交换结构化的数据。这就是说:SIP的重点是终端之间连接的建立和维护,连接以后的数据和信息传送他不关注;而XMPP重点是考虑终端组内部的数据交换,连接建立是基本的功能,而不是重点。所以,XMPP对应用的支持和扩展性的考虑很充分,比SIP天生要好。

(2) SIP is text based request response protocol and XMPP is XML based client server architecture.

SIP的信令和消息传送是基于文本的,是平面化(Flat)的数据表达,解析起来缺少规律性,在新增数据消息体的时候缺少继承性,需要开发新的代码来封装和解析,原有代码的继承性比较差。而XMPP采用开放的标准的XML表达,是一种结构化的消息结构,能够方面表达层次化的消息内容,表达内容的内在逻辑。这种XML的结构对应用的扩展和内容的解析带来极大的方便,大量软件代码可以重复利用。

(3) SIP signalling messages go via SIP headers and body whereas in XMPP messages passes via streaming pipe. XMPP sends request, response, indication or error using XML via the streaming pipe.

SIP信令由SIP报文格式的头部和内容两部分组成,也就是说,SIP报文格式的头部已经包含了部分内容,类似于HTTP,与具体的上层应用直接关联,而不是通用的报文格式;而XMPP所有信息都是采用XML在流管道之间透明传送。

SIP的连接建立通道与数据传送通道是各自独立的,连接建立在SIP client与Server之间,而数据传送通道是在Client–Client之间直接进行的。这个对视频、语音和文件传送业务很合适,但是不适合其他形式的应用。

XMPP的控制和数据通道是一体的,Clent只与Server建立连接,而Client与client之间是没有之间连接的。Client之间传送的通道是:Client1—〉Server1—〉server2—〉client2。这种方式看起来扩展性差,server压力很大,但是能够实现很好的业务功能,比如留言、广播、群聊、状态更新、Blog、微博、数据共享等等。

这种Client-server模型,很多业务的控制在Server上完成,新功能的增加在server上实现,在server上定义新的XML对象和逻辑,客户端只要负责XML数据流的解析和呈现就可以了。所以,终端实现简单。

(4) SIP runs over UDP, TCP and TLS whereas XMPP uses TCP and TLS only.

(5) In SIP, user agent could be server or client hence user agent can send or receive messages whereas in XMPP client only initiates requests to server so it will work with NAT and Firewall.

SIP是双向对称,客户端和服务器都可以主动发起连接请求并响应,这种对称连接的方式在穿越NAT和firewall的时候,带来很大的复杂性,无法保证穿越NAT。而XMPP是单向的连接,只有Client可以向Server发起连接请求,server不会向Client发起连接。这样便于NAT和firewall的穿越。

(6) Both SIP and XMPP are easy to implement.

Technically comparing SIP and XMPP is like comparing apples and oranges because the core protocols serve different purposes: session rendezvous/establishment vs structured data exchange

技术上比较SIP和XMPP,就像苹果与橙子相比,因为核心协议服务的目的不一样:连接汇聚/建立功能和结构化的数据交换功能。各自在其固有的领域有各自的优势,但是两者体系架构的差异,在未来的竞争中,个人觉得XMPP/Jingle架构更加有竞争力。因为XMPP的开放性,开发了大量的开源代码和开源应用,大量是非连接的业务,如即时通信、blog、微博、社交网络、远程控制、设备管理、三屏切换等等应用,已经有了基于XMPP开源代码和应用提供。Google在XMPP增加了Kingle,也很好地实现了基本的语音和视频通讯业务。

  基于XMPP的即时通信系统主要是Google Talk,还有基于Jabber的很多组织,最近Skype宣布支持急于XMPP协议,实现与XMPP IM的互通,微软也宣布MSN开始正式正式支持XMPP,facebook也宣布正式支持XMPP.所以,XMPP成为IM的互通比较已经初步确定,并且有一统天下的趋势.

社交网络好友关系数据库设计

好友关系设计在社交网络扮演重要的角色,以此来连接所有人。本片文章将介绍好友关系的数据库设计。这将对你设计的关系网络提供一个新的启发

https://app.box.com/s/oot5n9suwo3nw6oeyr8z

上述连接提供好友基本关系,同时具有类似facebook好友功能

数据库关系图

下面是好友关系数据设计的关系图

Note: One thing you can do to speed up the retrieval and insert operations is to keep the foreign key only in design and not to implement it in the Database. You must check the constraints programmatically rather than using database constraints.

Database Schema
数据库关系图

用户表

这张标包含4个字段 user_id 作为自增主键

关系表

前两个字段是需要关联的两个用户id, status 标示这两个用户的关系状态

Status 字段状态

Code Meaning
0 Pending 待定
1 Accepted同意
2 Declined 拒绝
3 Blocked   阻止

 

用整形代替字符串表示状态, 可以提高数据库性能

Action User

action_user_id 代表最近更新了status字段的用户id

举例,

如果用户1 像用户2发送了一个请求, 那么action_user_id就是1, 所以 发送好友请求的就是用户1.

如果用户2阻止了用户3, 那么用户2就应该是action_user_id. 用户2组织了用户3

唯一索引

为了不重复添加好友关系记录,我们给user_one_id和anduser_two_id增加一个UNIQUE索引, 这样避免重复的插入数据

它是如何工作的?

重要的是要记住,当你使用这个模型时候一定要确定 不管什么样的操作user_one_id总是要比user_two_id少. 下图是录入的好友关系数据截图.

下面是好友关系数据表

Sample relationship table data
Sample relationship table data

好友请求

插入一条好友请求. 用户1向用户2发起一个好友请求. 一旦一条记录插入到了这个关系表, 一个请求或者一个关系就已经在两个用户之间建立了. 你可以通过 statusaction_user_id 显示当前好友状态或者阻止好友请求

INSERT INTO `relationship` (`user_one_id`, `user_two_id`, `status`, `action_user_id`)
VALUES (1, 2, 0, 1)

 

同意好友请求

更新好友请求状态. 同意用户1发给用户2的好友请求.

UPDATE `relationship` SET `status` = 1, `action_user_id` = `2`
WHERE `user_one_id` = 1 AND `user_two_id` = 2

 

检查好友关系

检查任意两个用户是否是好友使用这个查询. 记住, user_one_id一定总是比user_two_id少. 如果返回一行结果, 那么这两个用户就是好友关系.

SELECT * FROM `relationship`
WHERE `user_one_id` = 1 AND `user_two_id` = 2 AND `status` = 1

 

好友列表

查看用户的所有好友. 这里用户1是登陆的用户.

SELECT * FROM `relationship`
WHERE (`user_one_id` = 1 OR `user_two_id` = 1)
AND `status` = 1

 

请求未决

获取用户1 所有未处理的好友请求. 假设用户1当前登陆.

SELECT * FROM `relationship`
WHERE (`user_one_id` = 1 OR `user_two_id` = 1)
AND `status` = 0
AND `action_user_id` != 1

 

用户的好友请求

当登陆的用户访问另一个用户的用户主页, 我们应该需要检索出两个人的好友关系状态. 这里, 用户1是当前登陆的用户. 用户1访问用户7的用户主页, 下面的查询可以检索出两个人的关系状态.

SELECT * FROM `relationship`
WHERE `user_one_id` = 1 AND `user_two_id` = 7

 

Friend Request Query Result
好友请求

上图是用户1向用户7发了一个好友请求. 根据状态我们可以知道他们不是好友. 使用下面的代码显示两人的关系状态

<?php
// Database connection code, $con is the database connection var.
// Now $row contains the query result.
// Logged in user id is stored in, $current_user_id. Profile user id is shown in $profile_user_id

switch ($row['status']) {
    case 0:
        if ($row['action_user_id'] === $current_user_id) {
            // Show, "Friend request sent" button. Show options to cancel the friend request.
        } elseif ($row['action_user_id'] === $profile_user_id) {
            // Show, "Accept Friend request" button. Show options to block and reject friend request.
        }
    break;
    case 1:
        // Check and show options to unfriend the user.
    break;
    case 3:
        // Check and show options to unblock. If the other user's visit's this profile show "profile does'nt exists"
    break;
}

 

原文出自: http://www.codedodle.com/2014/12/social-network-friends-database.html

翻译: xxtime.com

延伸阅读:
http://www.9lessons.info/2013/05/message-conversation-database-design.html
http://www.9lessons.info/2014/03/facebook-style-friend-request-system.html

linux 环境变量与动态链接库

# 指定动态链接库
/etc/ld.so.conf
/etc/ld.so.conf.d/

# 检查是否是动态链接库
ldd /bin/rm

# 指定环境变量(安全推荐)
~/.bash_profile
~/.bashrc

# 指定环境变量 所有用户
# 尽量不要修改/etc/profile, 可再/etc/profile.d/ 加入配置
/etc/profile
/etc/profile.d/

/etc/bashrc

# 让bash_profile环境变量立即生效的三种办法
1 . .bash_profile
2 source .bash_profile
3 exec bash –login

团队协同工具

团队是指为了实现某一目标而由相互协作的个体所组成的群体,它可以调动团队成员的所有资源和才智,但是如果没有团队协作,企业将可能会因为团队的内耗和冲突导致项目无法完成,从而浪费了大量时间金钱和资源。

那么,怎样才能让团队得到有效的协作,在网络时代,哪些是常用的团队协作工具,本文列举了世界上主要的10个企业团队协作工具,供大家参考。对于中国用户来说,有些产品可以借鉴。

十大团队协同工具

Skype

Skype在办公领域的应用十分广泛,家用也比较普及,大多数人每天都在使用Skypy用于工作和休闲,Skype被赋予“伟大”的协同工具,团队成员可以使用其进行头脑风暴,或者针对客户快速反应,以及轻松的聊天会话,同时还支持远程协助。(译者注:对于中国用户来说,腾讯QQ也和Skype具有几乎完全相同的功能和用处)

Yammer

Yammer可不仅仅是一个企业社交网站而已,它提供了各种各样的信息流和文章等,Yammer也鼓励员工有不同的想法,让员工更专注于工作,而不必担心因为上网而分心。Yammer是整合跨部门协同的有效服务。

Projectmanager.com

Projectmanager成立于2008年,由四个开发出来,提供一个项目管理的创新型工具,如今,Projectmanager已在全球100多个国家和地区拥有了客户,是发展快速的互联网项目管理服务。

Google Docs

Google Docs已经发布了很长一段时间,目前已经成为一个适合所有类型团队的稳定的协同工具,同时,这也是团队内多人共同编辑一个文档的最简单的途径。

Teambox

Teambox是一个创新的项目管理系统,专注于协同开发,支持项目成员的实时交流沟通。

Facebook Member Pages

在Facebook上创建一个封闭的群组并没有什么新鲜的,很多企业都将社区转向了这个平台,员工随时都可以在上面发布和工作相关的任务,并和那些在不同时期的同事进行协同。

Basecamp

Basecamp是目前世界头号项目管理软件之一,它提供了to-do list、Wiki类型的文档编辑、文件共享、事件跟踪和消息系统。它还支持世界上多种不同的语言,不过不支持中文。

Status.net

Status.net支持用户通过桌面或移动应用程序访问微博、文件共享和群组,也支持使用自定义域名以及其他社交网络的接口。

GoToMeeting

GoToMeeting不止提供电子邮件或即时通讯,还支持主管经理发布会议邀请,进行VoIP音频会议,这是一个适合中小型企业的非常简单的网络会议工具。

Socialcast

Socialcast是一个完全集成SharePoint、Outlook的微博工具,这个协作工具在管理界面上提供了一个分析套件。

随着互联网的发展,越来越多的公司开始依赖Internet上的在线协同工具来提供公司内部团队以及与用户之间即时在线工作的能力,实现无缝、实时的通讯、任务跟踪或文档分享等功能,完成企业的低成本、高性能、高整合、智能化的综合管理。

AngularJS 路由,动态设定模板templateUrl

AngularJS 本身就涉及到了WEB开发理念中的MVC,即模型 视图 控制器
而在PHP开发中已经有一套MVC的模型,难免有些晕
此段代码主要功能:根据URL动态参数变化,动态替换AngularJS所指定的模板
http://xxtime.com/index.html#/role/edit/2 指向 http://xxtime.com/role/edit?id=2
http://xxtime.com/index.html#/role/edit/3 指向 http://xxtime.com/role/edit?id=3
参数详解:
url: 是匹配的url规则
templateUrl: 是指定模板,此参数可以
参考
https://github.com/angular-ui/ui-router/wiki/URL-Routing#url-parameters.
https://github.com/angular-ui/ui-router/wiki

上代码:

// 编辑角色
.state('/role/edit', {
    url: "/role/edit/:id", //url: "/role/edit?id",
    templateUrl: function($routeParams) {
        return '/role/edit?id=' + $routeParams.id + '&_=' + Math.random(); //new Date().getTime();
    },
    data: {pageTitle: '编辑角色'},
    controller: "GeneralPageController",
    resolve: {
        deps: ['$ocLazyLoad', function($ocLazyLoad) {
            return $ocLazyLoad.load([{
                name: 'MetronicApp',
                insertBefore: '#ng_load_plugins_before',
                files: []
            }]);
        }]
    }
})

url 后面增加了js随机数 防止缓存 Math.random()

题记:这小破段代码搞了我好久,在stackoverflow搜索到答案后,满脑子的草泥马飞过。靠,真想骂人。搞了很久,原来这样

 

 

@2015-09-30 补充通用路由

// 通用路由
        .state('general', {
            url: "/:controller/:action/:id",
            templateUrl: function ($routeParams) {
                return '/' + $routeParams.controller + '/' + $routeParams.action + '?id=' + $routeParams.id + '&_=' + Math.random();
            },
            data: {pageTitle: 'XXTIME', pageSubTitle: 'manage system'},
            controller: "GeneralPageController",
            resolve: {
                deps: ['$ocLazyLoad', function ($ocLazyLoad) {
                    return $ocLazyLoad.load([{
                        name: 'MetronicApp',
                        files: [
                            'js/controllers/GeneralPageController.js'
                        ]
                    }]);
                }]
            }
        })

        // 通用路由2
        .state('general2', {
            url: "/:controller/:action",
            templateUrl: function ($routeParams) {
                return '/' + $routeParams.controller + '/' + $routeParams.action + '?_=' + Math.random();
            },
            data: {pageTitle: 'XXTIME', pageSubTitle: 'manage system'},
            controller: "GeneralPageController",
            resolve: {
                deps: ['$ocLazyLoad', function ($ocLazyLoad) {
                    return $ocLazyLoad.load([{
                        name: 'MetronicApp',
                        files: [
                            'js/controllers/GeneralPageController.js'
                        ]
                    }]);
                }]
            }
        })

        // 通用路由3
        .state('general3', {
            url: "/:controller",
            templateUrl: function ($routeParams) {
                return '/' + $routeParams.controller + '/?_=' + Math.random();
            },
            data: {pageTitle: 'XXTIME', pageSubTitle: 'manage system'},
            controller: "GeneralPageController",
            resolve: {
                deps: ['$ocLazyLoad', function ($ocLazyLoad) {
                    return $ocLazyLoad.load([{
                        name: 'MetronicApp',
                        files: [
                            'js/controllers/GeneralPageController.js'
                        ]
                    }]);
                }]
            }
        })

php分页,bootstrap样式分页上一页 下一页 首页 末页

自己写了一个分页方法,大家用的话可以自己包装下,弄一个类方法

样式参考 http://getbootstrap.com/components/#pagination-default

上代码

/**
 * 分页方法
 * @param int $total 总条数
 * @param int $page 当前页
 * @param string $urlFormat URL格式 如: ?page=
 * @param string $onclick = JavascriptSubmit(#page#);
 * @param array $config =array('size'=>20, 'letter'=>3, 'showType'=>'all');
 * @return string
 */
function page($total = 1, $page = 1, $urlFormat = '?page=', $onclick = '', $config = array())
{
    // 样式参考 http://getbootstrap.com/components/#pagination-default

    // 样式设定
    $letter = isset($config['letter']) ? $config['letter'] : 3;
    $showType = isset($config['showType']) ? $config['showType'] : 'all';
    $size = isset($config['size']) ? $config['size'] : 20;

    $pre = $next = $after = $before = '';
    $total_pages = ceil($total / $size);

    // 首页
    if ($page == 1) {
        $first_page = "<li class='disabled'><a href='javascript:;' class='disabled'>First</a></li>";
    } else {
        $on = str_replace('#page#', 1, $onclick);
        $first_page = "<li><a onclick='{$on}' href='#url#1'>First</a></li>";
    }

    // 末页
    if ($page == $total_pages) {
        $last_page = "<li class='disabled'><a href='javascript:;' class='disabled'>Last</a></li>";
    } else {
        $on = str_replace('#page#', $total_pages, $onclick);
        $last_page = "<li><a onclick='{$on}' href='#url#{$total_pages}'>Last</a></li>";
    }

    // 当前页
    $current = "<li><a href='javascript:;' class='active'>{$page}<span class='sr-only'>(current)</span></a></li>";

    // 前一页
    if ($page == 1) {
        $pre = "<li class='disabled'><a href='javascript:;'><span aria-hidden='true'>&laquo;</span><span class='sr-only'>Previous</span></a></li>";
    } else {
        $n = $page - 1;
        $on = str_replace('#page#', $n, $onclick);
        $pre = "<li><a onclick='{$on}' href='#url#{$n}'><span aria-hidden='true'>&laquo;</span><span class='sr-only'>Previous</span></a></li>";
    }

    // 后一页
    if ($page == $total_pages) {
        $next = "<li class='disabled'><a href='javascript:;'><span aria-hidden='true'>&raquo;</span><span class='sr-only'>Next</span></a></li>";
    } else {
        $n = $page + 1;
        $on = str_replace('#page#', $n, $onclick);
        $next = "<li><a onclick='{$on}' href='#url#{$n}'><span aria-hidden='true'>&raquo;</span><span class='sr-only'>Next</span></a></li>";
    }

    // body页
    for ($i = 0; $i < $letter; $i++) {
        $n = $page - $letter + $i;
        if ($n > 0) {
            $on = str_replace('#page#', $n, $onclick);
            $before .= "<li><a onclick='{$on}' href='#url#{$n}'>{$n}</a></li>";
        }
    }
    for ($i = 1; $i <= $letter; $i++) {
        $n = $page + $i;
        if ($n <= $total_pages) {
            $on = str_replace('#page#', $n, $onclick);
            $after .= "<li><a onclick='{$on}' href='#url#{$n}'>{$n}</a></li>";
        }
    }

    // 展示类型
    if ($showType == 'all') {
        $html = $first_page . $pre . $before . $current . $after . $next . $last_page;
    } elseif ($showType == 'pn') {
        $html = $pre . $before . $current . $after . $next;
    } elseif ($showType == 'fl') {
        $html = $first_page . $before . $current . $after . $last_page;
    } else {
        $html = $before . $current . $after;
    }
    if (!$urlFormat) {
        $preg = "/href='#url#[0-9]*'/i";
        $html = preg_replace($preg, "href='javascript:;'", $html);
    }
    $html = '<nav><ul class="pagination">' . str_replace('#url#', $urlFormat, $html) . '</ul></nav>';
    return $html;
}

XAMPP oracle for Mac OS

题外话:

最近发现我的文章被很多网站copy,图片都盗链的我的,我辛辛苦苦写的文章就变成你的了 ?过分了啊!加个出处链接也行啊!太过分了!

题记:
用了很久Linux,在linux上开发习惯了,后来用mac本本,发现这本本搭建开发环境很是痛苦啊。
我向来是喜欢手动源程序编译mysql php nginx 等等。
我需要的环境略微有点复杂,mysql pdo oci8 soap mongodb redis memcache phalcon 结果发现 编译mysql 和 php 问题很多啊,折腾许久有结果了,却不理想。
所以一直以来我用的都是virtualBox运行的CentOS作为开发环境,
但是virtualBox存在一个缓存问题,参见我以前的文章 http://blog.xxtime.com/961
总不是长久之计,于是先改用xampp吧,对我而言xampp常用的环境基本都差不多了,只是oracle的oci8拓展没有安装

第一步:下载 instantclient_11_2 这里我下载的是64位的
下载页面 http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html
下载 instantclient-basic-macos.x64-11.2.0.4.0.zip 和 instantclient-sdk-macos.x64-11.2.0.4.0.zip
分别解压后 把 sdk移动到instantclient_11_2里面
然后把合并的instantclient_11_2移动到 /usr/local/oracle/lib/instantclient_11_2

注:其实xampp自己有一个目录是instantclient,也可以无需下载(我没测过,嘻嘻),位置在:/Applications/XAMPP/xamppfiles/lib/instantclient-11.2.0.3.0

第二步:创建软连
进入目录/usr/local/oracle/lib/instantclient_11_2

cd instantclient_11_2
ln -s libclntsh.dylib.11.1 libclntsh.dylib
ln -s libocci.dylib.11.1 libocci.dylib

第三步:xcode环境软连接,如已经操作过可忽略

sudo ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/ /usr/include

第四步:安装oci8

sudo /Applications/XAMPP/xamppfiles/bin/pecl install oci8

等待一会儿,直到要求录入信息时候填写:
instantclient,/usr/local/oracle/lib/instantclient_11_2

第五步:
编辑 /Applications/XAMPP/xamppfiles/etc/php.ini
在里面加入一行:extension=oci8.so

第六步:配置环境变量DYLD_LIBRARY_PATH,编辑文件/Applications/XAMPP/xamppfiles/bin/envvars

sudo vim /Applications/XAMPP/xamppfiles/bin/envvars

修改类似这样:
其中/usr/local/oracle/lib/instantclient_11_2是oracle instantclient的位置

if test "x$DYLD_LIBRARY_PATH" != "x" ; then
  DYLD_LIBRARY_PATH="/Applications/XAMPP/xamppfiles/lib:/usr/local/oracle/lib/instantclient_11_2:$DYLD_LIBRARY_PATH"
else
  DYLD_LIBRARY_PATH="/Applications/XAMPP/xamppfiles/lib:/usr/local/oracle/lib/instantclient_11_2"
fi
export DYLD_LIBRARY_PATH

第七步:重启xampp

本文参考参考
http://www.binaryline.co.th/archives/132/comment-page-1
http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html

php pdo 连接报错 Connection failed: SQLSTATE[HY000] [2002] No such file or directory

错误

Connection failed: SQLSTATE[HY000] [2002] No such file or directory

环境概述:
MacOS
xampp 搭建的开发环境 apache mysql php
xampp 已支持mysql oracle 测试ok,且 phpinfo已上显示支持pdo_mysql pdo_pgsql pdo_sqlite
其中mysql我用的是brew包管理安装到机器里面的,而非xampp自带的mysql

php pdo 连接报错 Connection failed: SQLSTATE[HY000] [2002] No such file or directory
开始以为找不到文件是因为 url rewrite导致的,(因为从nginx切换到apache)结果跟踪程序发现是 new pdo 报错

经过搜索一些资料研究发现:
这个是php.ini配置文件中pdo_mysql.default_socket指定的mysql.sock路径不对
我的mysql.sock文件在 /private/tmp/mysql.sock
所以要设置:

pdo_mysql.default_socket=/private/tmp/mysql.sock

如果不知道自己的mysql.sock在哪里可以搜索(因为编译安装,和yum、apt-get、或者brew等包管理工具安装的位置不一样)

sudo find / -name ‘mysql.sock’

参考 http://www.xuebuyuan.com/1659711.html