kafka安装及Kafka-PHP扩展的使用
话说用了就要有点产出,要不然过段时间又忘了,所以在这里就记录一下试用Kafka的安装过程和php扩展的试用。 下面就开始讲Kafka的安装吧。我以CentOS6.4为例,64位。 一. 首先确认下jdk有没有安装 使用命令 [root@localhost ~]# java -version java version “1.8.0_73” Java(TM) SE Runtime Environment (build 1.8.0_73-b02) Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode) 如果有以上信息的话,就往下安装吧,有些可能是jdk对不上,那就装到对的上的。如果没有安装,就看一下下面的jdk安装方法: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 到这个地址下载jdk8版本,我下载的是jdk-8u73-linux-x64.tar.gz,然后解压到/usr/local/jdk/下。 然后打开/etc/profile文件 [root@localhost ~]# vim /etc/profile 把下面这段代码写到文件里 export JAVA_HOME=/usr/local/jdk/jdk1.8.0_73 export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar export PATH=$JAVA_HOME/bin:$PATH 最后 [root@localhost ~]# source /etc/profile 这时jdk就生效了,可以使用 java -version验证下。 二. 接下来安装Kafka 1. 下载Kafka 到http://kafka.apache.org/downloads.html下载相应的版本,我使用的是kafka_2.9.1-0.8.2.2.tgz。 […]
centos7 php7.0 升级到php7.1
备份之前的php7.0(这很重要,非常重要) 如果这一步没有做的话,直接升级,我敢确定90% 你服务器就挂了,至于为什么呢,因为你之前的配置都没有了呗,而新安装的php7.1 配置是新的,没有了各种扩展,你服务器怎么跑起来。当然如果你什么扩展都没有安装,恭喜你,你可以不用备份 cp -P /usr/local/php /usr/local/php70 查看php7.0的configure 既然是升级,当然configure只能比以前多而不能少了,如果你忘记了以前的configure(肯定没人记得),查看phpinfo php -i | grep configure 替换一下就可以获得之前的configure 命令 php -i | grep configure | sed -e “s/Configure Command => //; s/’//g” 下载php7.1源码 cd /usr/local/src wget -c http://cn2.php.net/get/php-7.1.0.tar.gz/from/this/mirror -O php-7.1.0.tar.gz tar -zxvf php-7.1.0.tar.gz cd php-7.1.0/ 开始安装7.1 cd php-7.1.0 ./configure –prefix=/usr/local/php –exec-prefix=/usr/local/php –bindir=/usr/local/php/bin –sbindir=/usr/local/php/sbin –includedir=/usr/local/php/include –libdir=/usr/local/php/lib/php –mandir=/usr/local/php/php/man –with-config-file-path=/usr/local/php/etc –with-mhash –with-openssl –with-mcrypt –enable-mysqlnd –with-mysqli=mysqlnd –with-pdo-mysql=mysqlnd –with-gd –with-iconv […]
Websocket原理
一、websocket与http WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算) 首先HTTP有 1.1 和 1.0 之说,也就是所谓的 keep-alive ,把多个HTTP请求合并为一个,但是 Websocket 其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充可以通过这样一张图理解 有交集,但是并不是全部。 另外Html5是指的一系列新的API,或者说新规范,新技术。Http协议本身只有1.0和1.1,而且跟Html本身没有直接关系。。通俗来说,你可以用HTTP协议传输非Html数据,就是这样=。= 再简单来说,层级不一样。 二、Websocket是什么样的协议,具体有什么优点 首先,Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说。简单的举个例子吧,用目前应用比较广泛的PHP生命周期来解释。 HTTP的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次HTTP请求就结束了。 在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。但是请记住 Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。 教练,你BB了这么多,跟Websocket有什么关系呢?_(:з」∠)_好吧,我正准备说Websocket呢。。 首先Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手。 首先我们来看个典型的 Websocket 握手(借用Wikipedia的。。) GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Origin: http://example.com 熟悉HTTP的童鞋可能发现了,这段类似HTTP协议的握手请求中,多了几个东西。我会顺便讲解下作用。 Upgrade: websocket Connection: Upgrade 这个就是Websocket的核心了,告诉 Apache 、 Nginx 等服务器:注意啦,我发起的是Websocket协议,快点帮我找到对应的助理处理~不是那个老土的HTTP。 Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 首先, Sec-WebSocket-Key 是一个 Base64 encode 的值,这个是浏览器随机生成的,告诉服务器:泥煤,不要忽悠窝,我要验证尼是不是真的是Websocket助理。 然后, Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。简单理解:今晚我要服务A,别搞错啦~ 最后, Sec-WebSocket-Version 是告诉服务器所使用的 Websocket Draft(协议版本),在最初的时候,Websocket协议还在 Draft 阶段,各种奇奇怪怪的协议都有,而且还有很多期奇奇怪怪不同的东西,什么Firefox和Chrome用的不是一个版本之类的,当初Websocket协议太多可是一个大难题。。不过现在还好,已经定下来啦~大家都使用的一个东西~ 脱水: 服务员,我要的是13岁的噢→_→ 然后服务器会返回下列东西,表示已经接受到请求, 成功建立Websocket啦! […]
emoji表情 Unicode代码大全
emoji表情有很多种版本,其中包括Unified、DoCoMo、KDDI、Softbank和Google,并且不同版本用于表示同一符号表情的Unicode代码也不相同。本篇文章,给出SoftBank(日本软银集团)版本的emoji表情代码表(网上一般称之为SB Unicode,指的就是它):
php判断字符串长度 isset()速度比strlen()更快
在php里当需要判断一个字符串长度时,我们首先想到的是strlen()函数,不错,strlen()返回的就是字符串的长度,这样使用没有任何问题。不过,如果要从php程序优化的角度来看,使用strlen()判断字符串长度未免是最好的写法。 程序的优化,需要经验的积累,那是知识的沉淀,厚积薄发的体现。 有经验的程序员发现,php判断字符串长度,使用isset()在速度上比strlen()更快,执行效率更高。 因此,今天就分析一下strlen()和isset()这两个函数。 PHP strlen() 函数 定义和用法 strlen() 函数返回字符串的长度。 语法 strlen(string) 参数:string 描述:必需。规定要检查的字符串。 实例 <?php echo strlen(“Hello world!”); ?> 输出: 12 PHP isset() 函数 isset函数是检测变量是否设置。 格式: bool isset ( mixed var [, mixed var [, …]] ) 返回值: 若变量不存在则返回 FALSE 若变量存在且其值为NULL,也返回 FALSE 若变量存在且值不为NULL,则返回 TURE 同时检查多个变量时,每个单项都符合上一条要求时才返回 TRUE,否则结果为 FALSE 如果已经使用 unset() 释放了一个变量之后,它将不再是 isset()。若使用 isset() 测试一个被设置成 NULL […]
不要使用(include/require)_once
最近关于apc.include_once_override的去留, 我们做了几次讨论, 这个APC的配置项一直一来就没有被很好的实现过. 在这里, 我想和大家在此分享下, 这个问题的原因, 以及对我们的一些启示. 关于使用include还是include_once(以下,都包含require_once), 这个讨论很长了, 结论也一直有, 就是尽量使用include, 而不是include_once, 以前最多的理由的是, include_once需要查询一遍已加载的文件列表, 确认是否存在, 然后再加载. 诚然, 这个理由是对的, 不过, 我今天要说的, 是另外一个的原因. 我们知道, PHP去判断一个文件是否被加载, 是需要得到这个文件的opened_path的, 意思是说, 比如: <?php set_include_path(“/tmp/:/tmp2/”); include_once(“2.php”); ?> 当PHP看到include_once “2.php”的时候, 他并不知道这个文件的实际路径是什么, 也就无法从已加载的文件列表去判断是否已经加载, 所以在include_once的实现中, 会首先尝试解析这个文件的真实路径(对于普通文件这个解析仅仅类似是检查getcwd和文件路径, 所以如果是相对路径, 一般是不会成功), 如果解析成功, 则查找EG(include_files), 如果存在则说明包含过了, 返回, 否则open这个文件, 从而得到这个文件的opened_path. 比如上面的例子, 这个文件存在于 “/tmp2/2.php”. 然后, 得到了这个opened_path以后, PHP去已加载的文件列表去查找, 是否已经包含, 如果没有包含, 那么就直接compile, 不再需要open file了. […]
apache通过user-agent和.htaccess(rewrite)判断网站跳转
首先要确实服务器是使用apache服务来提供Web服务的,并加载了mod_rewrite模块,具体加载mod_rewrite模块方法,网上有详细教程,请自行百度。 让apache服务器支持.htaccess 只要简单修改一下apache的httpd.conf配置就可以让APACHE支 持.htaccess了:AllowOverride None 修改为: AllowOverride All 启用.htaccess后,在现有普通网站基础上,再新建一个手机网站,也可以在现有网站根目录下新建子目录,如现有网站为www.baidu.com,新建手机站为m.baidu.com,或者新建子目录方式:www.baidu.com/m/ 普通站和手机站使用相同数据库,程序相同,只是显示用的模板不同。 ***在普通网站根目录下新建 .htaccess 文件: # 将 RewriteEngine 模式打开RewriteEngine OnRewriteBase /# Rewrite 规则 判断用户浏览器类型,如果是手机就跳转到手机网站RewriteCond %{HTTP_USER_AGENT} “(baidu.Transcoder|mini|android|blackberry|googlebot-mobile|iemobile|Mobile|ipad|iphone|ipod|opera mobile|palmos|webos|ucweb|Windows Phone|Symbian|hpwOS)” [NC]RewriteRule ^(.*)$ http://m.baidu.com/$1 [L,R=302] 上面的代码,自动判断手机用户然后跳转到手机网站,并带有相同的参数,如手机用户输入的网址是http://www.baidu.com/index.php?go=1那么系统跳转时会自动加上参数http://m.baidu.com/index.php?go=1。 这里需要说明下,因为RewriteRule ^(.*)$ http://m.baidu.com/$1 [L,R=302]的加入,如果手机页面中有需要访问非手机网站资源时,如其他子目录或二级网内容,就需要设置相应正则排除指定网站或文件,如: RewriteRule ^(.*?(?
PHP中$_SERVER的详细参数与说明
$_SERVER[‘PHP_SELF’] #当前正在执行脚本的文件名,与 document root相关。 $_SERVER[‘argv’] #传递给该脚本的参数。 $_SERVER[‘argc’] #包含传递给程序的命令行参数的个数(如果运行在命令行模式)。 $_SERVER[‘GATEWAY_INTERFACE’] #服务器使用的 CGI 规范的版本。例如,“CGI/1.1”。 $_SERVER[‘SERVER_NAME’] #当前运行脚本所在服务器主机的名称。 $_SERVER[‘SERVER_SOFTWARE’] #服务器标识的字串,在响应请求时的头部中给出。 $_SERVER[‘SERVER_PROTOCOL’] #请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。 $_SERVER[‘REQUEST_METHOD’] #访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT”。 $_SERVER[‘QUERY_STRING’] #查询(query)的字符串。 $_SERVER[‘DOCUMENT_ROOT’] #当前运行脚本所在的文档根目录。在服务器配置文件中定义。 $_SERVER[‘HTTP_ACCEPT’] #当前请求的 Accept: 头部的内容。 $_SERVER[‘HTTP_ACCEPT_CHARSET’] #当前请求的 Accept-Charset: 头部的内容。例如:“iso-8859-1,*,utf-8”。 $_SERVER[‘HTTP_ACCEPT_ENCODING’] #当前请求的 Accept-Encoding: 头部的内容。例如:“gzip”。 $_SERVER[‘HTTP_ACCEPT_LANGUAGE’]#当前请求的 Accept-Language: 头部的内容。例如:“en”。 $_SERVER[‘HTTP_CONNECTION’] #当前请求的 Connection: 头部的内容。例如:“Keep-Alive”。 $_SERVER[‘HTTP_HOST’] #当前请求的 Host: 头部的内容。 $_SERVER[‘HTTP_REFERER’] #链接到当前页面的前一页面的 URL 地址。 $_SERVER[‘HTTP_USER_AGENT’] #当前请求的 User_Agent: 头部的内容。 […]
PHP里 switch case条件语句的问题
<?php $a = “abc”; switch ($a) { case 0:echo “a 为 0”;break; case “cdaf”:echo “a 为 cdaf”;break; case “abc”: echo “a 为 abc”;break; default:echo “a 什么都不是”;break; } ?> 运行这段代码为什么输出的结果是‘a为0’ 而不是‘a为abc’?这个0有什么玄机呢? 这个问题应该从PHP作为动态脚本语言说起:动态语言的变量类型是随存储的变量而变化的,即变量类型是根据具体环境而进行变化的。字符串”abc”,指确切字符串,但是对于PHP存储的时候它是不能确定的,因为随着语义的变化,其所起的作用也会变化第一个 case 0:, PHP脚本将常量0翻译为确切的整数,与字符串比较大小时,需要将字符串转换为整数。PHP脚本会将字符串abc,从十进制(默认)转换为数字,但是abc很明显不能代表十进制数,即转换失败,则PHP将结果置为0,如果将字符串表示为”0xabc”,那么PHP脚本能够发现0x标识,将abc作为十六进制转换,所以能够得到abc标识的十六进制整数。从C语言可以做一个简单比较:C中的case必须是数字常量,而不能是字符串,就因为C是变量类型确定的,运行时不能将确定的变量按语义随意转换。而PHP可以,因为PHP语言是动态的,变量类型是动态的。或者从PHP的例子中学习:如果一个文件将111111字符串(不是数字)存储到文件,然后从文件直接读取到变量$a,如下语法就可以将$a作为整数计算: 0+$a 上述表达式得到的结果也可以作为动态语言的一个变现来看
CI加载流程及结构分析(一)
入口文件入口文件主要完成下列工作: 1. 指定 CodeIgniter 框架所在目录; 2. 定义 APPPATH 常量,指示应用程序文件根目录; 3. 载入 codeigniter/CodeIgniter.php 文件,启动框架。 codeigniter/CodeIgniter.php 文件这个文件是 CodeIgniter 的基本文件,主要完成初始化 CodeIgniter 框架和启动应用程序两项工作。 1. 实例化 CI_Benchmark,这个类用于标记应用程序执行消耗的时间; 2. 载入应用程序的配置文件 require(APPPATH.?config/config‘.EXT); 3. 实例化 CI_Config,这个类用于将数组封装为可以操作的配置服务; 4. 实例化 CI_Router,这个类用于分析 URL 请求,确定要执行的控制器和动作; 5. 实例化 CI_Output,这个类提供输出内容的缓存和检查服务; 6. 通过 $OUT->_display_cache($CFG, $RTR) 尝试输出缓存内容,如果成功,则结束程序运行; 7. 判断控制器类定义文件是否存在。如果不存在则通过 show_404() 显示错误信息; 8. 实例化 CI_Input,这个类提供对 $_GET、$_POST 的访问手段,并封装了一些过滤方法; 9. 实例化 CI_URI,这个类提供对 URL 的分析、构造服务; 10. 实例化 CI_Language,这个类提供多语言字符串映射服务; 11. 载入 codeigniter/Base4.php 或者 codeigniter/Base5.php; 12. 载入 libraries/Controller.php; 13. 载入控制器类定义文件; 14. 实例化控制器类; 15. 如果控制器使用了 scaffolding 功能,则调用控制器的 _ci_scaffolding() 方法,否则调用控制器动作方法; 16. 通过 $OUT->_display(); 输出内容($OUT 是 CI_Output 的实例)。 CI_Benchmark 这个类很简单,就是用 microtime() 函数记录时间点,并提供 elapsed_time() 方法来计算两个时间点之间消耗的时间。这个类功能不多,但是很实用。CodeIgniter 中大部分类都是这种设计思想,值得称赞! CI_Config 这个类其实是在内部维护了一个数组,用来记录应用程序的设置(类似 Windows 注册表)。这种简单的封装可以强制应用程序按照固定的规范访问设置,同时又不将设置保存为全局变量,避免无意中遭到破坏或篡改。 CI_Router CI_Router 功能很单一。CI_Router 首先分析出应用程序当前使用的 URL 模式:PATHINFO 或普通模式。接下来从 URL 地址中分析出控制器名字、动作名以及参数名和参数值。分析的结果保存为 CI_Router 对象实例的成员变量。这里比较有特点的是,CI_Router 可以根据开发者在应用程序设置里面定义的模式来分析 URL,而不是使用某种固定的模式。 CI_Output CI_Output 有两个主要功能:获得应用程序执行的所有输出内容和输出缓存服务。应用程序执行的输出结果都会保存为 CI_Output 的成员变量。然后根据应用程序设置,CI_Output::_display() 方法会调用 CI_Output::_write_cache() 方法将输出内容缓存起来。下一次当使用 CI_Output::_display_cache() 时如果缓存已经建立了,并且没有过期,则会直接输出缓存内容。在 CI_Output::_write_cache() 中,是根据 URL 地址和 URL 参数来确定缓存 ID 的。因此即便是同一个控制器和动作,只要使用不同的 URL 参数,也会缓存不同的内容。这个类的功能很简单,因此在许多动态页面是无法使用的。例如用户登录前和登录后,访问同一个控制器和动作并使用相同的 URL 参数,页面内容也有可能是不同的。这时,CI_Output 的缓存就不能使用。因为从本质上来说,CI_Output 提供的缓存是在应用程序之外的,所以应用程序无法根据当前状态来决定是否缓存页面。当一个页面被缓存后,对该页面的访问实际上根本就不会执行应用程序代 码,而是由 CI_Output 取出缓存内容直接就输出了。 CI_Input CI_Input 是输入数据过滤器,并且提供了对 $_GET、$_POST 的封装服务。例如用 CI_Input::post() 方法来访问 $_POST。由于多了这层封装,CI_Input 可以在 post() 方法中对数据进行更多的过滤。这种封装从出发点上看,是很不错的。但是这也会造成一些问题。例如 CI_Input 只有在调用 post() 方法时才能进行过滤。如果应用程序使用 $_POST 直接获取数据,那么实际上就绕过了安全屏障。如果应用程序使用了第三方库,那么这种风险更大,因为第三方库很可能会直接使用 $_POST 等全局变量。因此有些开发者认为过滤应该是全局的,即在框架初始化时,就对所有输入数据进行过滤。但初始化时的全局过滤灵活性很差,要么全过滤,要么都不 过滤,没法做到对个别数据的单独过滤。 CI_Input 的另一个问题,就是没有处理 magic_quotes。不管 magic_quotes 设置为什么,CI_Input 都没有对数据进行相关的处理。这样一来,如果服务器的 magic_quotes 设置不同,那么应用程序得到的数据也是不一致的。后来查看数据库驱动的代码,发现 CI_Input 将对 magic_quotes 的处理放到了数据库驱动中。这种设计是有很大缺陷的!如果应用程序取得数据后,并不是存入数据库(例如直接显示或存入文件),那么就必须自行判断 magic_quotes 的状态。这种判断不但烦琐,而且容易遗忘。所以框架有责任将所有数据整理为一致的格式,要么是应用 addslashes() 转义过后的数据,要么是没有转义的数据。奇怪的是 CI_Input 却对输入数据的字段名进行了 magic_quotes 检查,并应用了 addslashes()。这是为了让数据库字段名不会成为 SQL 注入攻击的根源。甚至,CI_Input 还会将 \n\r\n\r 替换为 \n。这种随意篡改原始数据的做法,非常不可取。总之,我个人认为 CodeIgniter 在这部分的设计是很糟糕的。不过要改善也很简单,几行代码就可以了。然后修改一下数据库驱动。但是由于已经有许多采用 CodeIgniter 开发的应用程序,所以这样的升级改动,影响是非常大的。 CI_URI 由于 CodeIgniter 允许应用程序定义 URL 映射模式,所以需要专门的工具来生成 URL 地址。CI_URI 就是完成这些工作的。 […]