PHP 7 编译安装 cannot stat ‘phar.phar’: No such file or directory

PHP 出来了应该尝尝鲜, 结果编译没问题, 安装的时候报了如下错误

cp -pR -f phar.phar /usr/local/php7/bin/phar
cp: cannot stat 'phar.phar': No such file or directory
make: *** [install-pharcmd] Error 1

解决方法很简单:

find . -name 'phar.phar'

找到 phar.phar 文件, 移动或者复制到安装指令执行的目录下就行了.

最后附上, 完成后的执行指令:

php5vsphp7

使用 strace 测试 Yii 2, Laravel 5, Phalcon 框架性能

本文为 虚伪的灵魂 版权所有, 禁止任何商业网站转载, 个人博客转载请于文章起始位置标明 “转载自 使用 strace 测试 Yii 2, Laravel 5, Phalcon 框架性能 – 虚伪的灵魂“.

一. 前言

最近在使用 Laravel, 公司项目上线后, 性能表现不尽如人意, 因为这样的情况, 才促使我去做这样一件测试框架性能的事情. 在朋友的提醒下, 我开始鼓捣起了 strace. strace 是用来追踪进程执行过程中对硬件操作(比如硬盘)时产生的系统调用和所接收的信号的. 本文中所用到的参数很简单, 就是 -c . strace -c 用来统计 php-fpm 在整个执行过程中的各种系统命令的调用数量以及耗时情况. 这已经能在很大程度上判别出一个框架的性能了.

二. 测试设计

  1. 测试对象: 原生PHP, Yii 2, Laravel 5.1 以及 Phalcon 2.
  2. 测试内容1: 测试对象以最快方式输出 “Hello, XXX”, 为了避免初始化的问题, 从第二次起开启 strace 性能追踪, 为避免单次误差, 所以性能追踪连续统计10次.
  3. 测试内容2: 在开启 Zend OPCache 的情况下, 再次完成上述测试, 以理解 OPCache 带来的性能提升, 但是OPCache 是存在内存限制的, 因此每次测试前都会重启 PHP-FPM 进程.

三. 测试代码

a. 原生PHP

<?php
echo 'Hello, World!';

b. Yii 2
新装好 Yii 2, 建立项目后直接修改默认控制器SiteController代码:

<?php

namespace app\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
use app\models\LoginForm;
use app\models\ContactForm;

class SiteController extends Controller {

    public function actionIndex() {
        return 'Hello, Yii 2!';
    }

}

c. Laravel 5.1
新装好 Laravel 5.1 后, 直接修改 routes.php 文件

<?php

Route::get('/', function () {
    return 'Hello, Laravel!';
});

d. Phalcon 2.
入口脚本

<?php

use Phalcon\Loader;
use Phalcon\Mvc\View;
use Phalcon\Mvc\Url as UrlProvider;
use Phalcon\Mvc\Application;
use Phalcon\DI\FactoryDefault;

try {
    $loader = new Loader();
    $loader->registerDirs(array(
        '../app/controllers/',
        '../app/models/'
    ))->register();
    $di = new FactoryDefault();
    $di->set('view', function(){
        $view = new View();
        $view->setViewsDir('../app/views/');
        return $view;
    });
    $di->set('url', function(){
        $url = new UrlProvider();
        $url->setBaseUri('/tutorial/');
        return $url;
    });
    $application = new Application($di);
    echo $application->handle()->getContent();
} catch(\Exception $e) {
     echo "PhalconException: ", $e->getMessage();
}

默认控制器 IndexController:

<?php

use Phalcon\Mvc\Controller;

class IndexController extends Controller {

    public function indexAction() {
        echo 'Helle, Phalcon!';
    }

}

四. 第一轮测试, 无 Zend OPCache

a. 原生测试结果:

origin

b. Yii 2 测试结果:

yii

C. Laravel 测试结果:

Laravel 第一轮第1次, 直接执行:

laravel

Laravel 第一轮第2次, 在执行过 composer dumpautoload –optimize 后:

laravel2

Laravel 第一轮第3次, 在执行过 php artisan optimize –force 后:

laravel3

D. Phalcon 测试结果:
phalcon2

五. 第一轮试验总结:

  1. 原生还是快的
  2. Laravel 没做优化速度简直感人
  3. Laravel 做完优化速度提升简直感人(自己体会两个感人
  4. 优化过的 Laravel 居然比 Yii 2 跑的快…颠覆了我的认知
  5. Phalcon 2 毫无悬念的在性能上完爆了 Yii 2 和 Laravel. 完全不通的数量级啊.
  6. 另外需要注意的是, 结果是执行10次总的统计数量.

六. 第二轮测试, 有 Zend OPCache.

a. 原生测试结果:

origin

b. Yii 2 测试结果:

yii

C. Laravel 测试结果:

laravel

D. Phalcon 测试结果:

phalcon

七. 第二轮试验总结:

  1. 原生还是快.
  2. Yii 2 性能上胜过了 Laravel.
  3. Phalcon 2 再次毫无悬念的在性能上完爆了 Yii 2 和 Laravel.

八. 试验总结:

  1. 未做 artisan optimize 的 Laravel 性能很差.
  2. OPCache 后的 Yii 2 性能才能胜过 Laravel.
  3. Phalcon 2 性能刚刚的毕竟是扩展级的.
  4. 只要有 PHP 文件就有, OPCache 都有优化的空间(好大一句废话).

九. 测试的不足之处

strace 只能追踪到进程针对硬件的调用, 程序内部的运算对CPU的占用及消耗, 并不能很好的体现出现出来. 比如框架本身存在如果比较大的运算量, 比如正则运算, 并不能很好的体现出来.

十. 思考

  1. Composer 在提供了便利安装依赖的同时是不是增加了性能的负担呢?
  2. Composer 依赖少的时候可能性能并不明显, 而依赖多的时候呢?

Ubuntu 下 PHP Solr 扩展的安装与使用

一. 安装

1. 下载扩展包

Pecl::Package::Solr 下载最新稳定版扩展包并解包

2. 安装基础库

安装 libcurl devel 文件:
sudo apt-get install libcurl4-gnutls-dev

安装 libxml2 devel 文件:
sudo apt-get install libxml2-dev

3. 编译安装扩展
phpize
./configure
make
sudo make install

4. 添加PHP 扩展配置
extension=solr.so

二. 使用

1. 启动实例

参考 SOLR 的安装使用 一文启动测试实例

2. 在实例中查询

<?php
$options = [
    'hostname' => '127.0.0.1',
    'wt' => 'json',
    'path' => 'solr/gettingstarted_shard1_replica1',
];
$client = new SolrClient($options);

$query = new SolrQuery;
$query->setQuery('lucene');
$query->addField('id');
$query->addField('name');
$query->addField('title');

$resp = $client->query($query);
$r = $resp->getResponse();

var_dump($r);

上面的代码中, 如果不清楚 SolrClient 的 $options 可以使用

$client->getOptions();

获取完整的参数, 然后尝试设置.

3. 添加文档到 Solr 中

<?php
$options = [
    'hostname' => '127.0.0.1',
    'wt' => 'json',
    'path' => 'solr/gettingstarted_shard1_replica1',
];
$client = new SolrClient($options);

$doc = new SolrInputDocument();
$doc->addField('id', 'solr.xwsoul.com');
$doc->addField('title', '虚伪的灵魂');
$doc->addField('description', '人人都是戴着面具而活, 我却连灵魂都是虚伪的.');
$doc->addField('tags', '技术');
$doc->addField('tags', 'Solr');
$response = $client->addDocument($doc);
$client->commit();

$query = new SolrQuery;
$query->setQuery('虚伪 灵魂');
$query->addField('id');
$query->addField('title');
$query->addField('description');
$query->addField('tags');

$resp = $client->query($query);
$r = $resp->getResponse();

var_dump($r);

至此, 我们已经可以简单的通过 PHP 操作 Solr 了.

Solr 的安装与快速启用

1. 安装 JDK

我用的Ubuntu 装的 Oracle-java-8

2. 下载最新版的 Solr

Apache Solr 下载最新版并解包, 写文章的时候当前最新版本为5.2.1.

3. 快速启动

1. 启动测试实例
bin/solr start -e cloud -noprompt
启动后, 通过在浏览器中打开 http://localhost:8983/solr/ 访问管理UI.

2. 建立索引
bin/post -c gettingstarted docs/
上述命令建立了 docs/ 目录下的富文件(rich file)内容的索引

3. 开始查询
点击 1 中打开的页面左侧的 Select Core, 选择任意分片, 点击 Query 后选择 Excute Query 即可开始查询.

参考文档: http://lucene.apache.org/solr/quickstart.html

Laravel 禁用 Cookie 输出

默认情况下 Laravel 会输出 token 等 Cookie.

而在默写情况下, 我们必须禁用这种输出, 比如使用了 ng 的缓存来缓存该页面, 这时候我们就需要禁用 Cookie 了.

在 Laravel 4 中我们可以使用如下代码解决:

<?php
Config::set('session.driver', 'array');

而在 Laravel 5 中, 我们就会遇到这样的错误:

Undefined index: _sf2_meta

经过一番搜索, 在L5中应该使用以下方式:

<?php
Session::setDefaultDriver(null);

Laravel 4 自定义用户登陆.

已经用了一段时间的 Laravel 了, 已经有点脑残粉的倾向了, 哈哈哈
再来谈谈 Laravel 松散设计的好处吧, 今天做用户登陆真的给我爽到了.

比如 Laravel 里的登录可以通过 Auth::attempt() 实现:

1. 如果你使用的加密方法与 Laravel 默认的不一样怎么办?

1) 写个加密器, 实现 Illuminate\Hashing\HasherInterface 接口的 make(实现加密), check(加密校验), needsRehash(是否重新生成) 三个方法.

2) 写个 Service Provider, 继承 Illuminate\Support\ServiceProvider, 用于注册服务.

3) 修改配置 config -> app.php -> providers 替换 Illuminate\Hashing\HashServiceProvider 为你的 HashServiceProvider.

2. 登陆完成 默认 session 里只存了 user 的 id.
获取用户的信息怎么办?

a. 使用 Auth::user()->xxx, Laravel 会默认帮你到数据库里获取.

如果不想查询数据库, 只想从 session 中获取怎么办? 通过监听事件解决:

<?php
//listen auth login action
Event::listen('auth.login', function() {
    $user = Auth::user();
    Session::put('name', $user->name);
    Session::put('email', $user->email);
});
//listen auth logout action
Event::listen('auth.logout', function() {
    Session::clear();
});

Laravel 在执行登录和登出的时候, 已经触发过登录和登出事件了.

诸如上述的设计, 有什么好处? 好处太明显了, 我只要关注我需要改动的地方就可以了, 其他方面框架都帮你解决了.这样可以实现代码的最大化公用.

再说回来, 如果框架代码本身耦合度太高的话, 实现这些东西比较麻烦, 因为逻辑和业务分离太麻烦, 造成的问题是, 很多情况下如果你要修改代码可能需要重写整个方法, 同时还得在方法中重载父类的方法.

Laravel 4 创建模块 Module.

模块作为一个整体, 便于开发和维护, 是一种有效的编码手段. Yii中原生, 支持模块, 那么 Laravel 支持这样的方式么? 答案是显然的. 不多废话, 上代码.

1. 新建路径组 Route::group 定义一组路径前缀

Route::group(array('prefix' => 'admincp', 'namespace' => 'Admin'), function () {
    Route::get('/', 'HomeController@index');
    Route::controller('home', 'HomeController');
});

上述代码中映射了 Admin 下的 HomeController.

2. 在控制器目录(controllers)下新建, Admin 目录, 再新建控制器 HomeController. HomeController 有3个要点:
1. namespace 的定义
2. 对控制器的继承, 使用 \Controller
3. 定义 missingMethod 方法, 用于响应路由的自动映射.
代码, 如下:

<?php namespace Admin;
class HomeController extends \Controller {
    public function missingMethod($params=array()) {
        $action = array_shift($params);
        return call_user_func_array([$this, $action], $params);
    }

    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index() {
        return 'backend.index';
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create() {
        return 'backend.create';
    }
}

这样, 就可以在 controllers/Admin 目录下尽情的, 玩耍了. 当然新建控制器的时候, 记得在 Route::group 下建立新的映射.

Laravel 4 映射整体路由到控制器.

不废话直接上代码…

1. route 通过 Route::controller 挂载到指定的 controller.
Route::controller('ajax', 'AjaxController');

2. 重写控制器的 missingMethod 方法.

public function missingMethod($params=array()) {
    $action = array_shift($params);
    return call_user_func_array([$this, $action], $params);
}

3. 如果不重写该方法, laravel 会自动调用 Illuminate\Routing\ControllermissingMethod方法. 此种情况下, 尽管你已经定义了期望的方法, 但任然会抛出 Controller method not found.的错误, 这提示真的很让人摸不着头脑.

人人都是戴着面具而活, 我却连灵魂都是虚伪的.