/images/avatar.jpg

webpack的使用

webpack时一个打包用于前端打包的应用,可以使用npm来安装

npm install webpack -g

使用-g表示全局安装,这样就可以直接使用webpack命令了

现在就让我们来一步步新建一个简单的React应用,并使用webpack来打包生成线上版本

首先,建立一个文件夹

mkdir lesson_1

进入文件夹中,我们先用npm初始化

npm init

一直回车直到最后提示使用yes确定即可

现在目录下多了个package.json

现在我们来安装依赖包

npm install --save-dev webpack react react-dom babel-core babel-loader babel-preset-es2015 babel-preset-react jsx jsx-loader

这里说下几个包都代表什么:

使用Phantomjs来处理针对js渲染的页面的爬取

对于爬虫来说,主要的任务就是获取页面的内容,从最初页面直接后端渲染结果后输出到后端输出模版再使用ajax等技术来渲染数据,而随着前端技术的发展,越来越多的网站开始使用纯js来渲染页面,比如Vue、React等。

而对于爬虫来说,想要获取页面内容,也从最初的直接拿到页面内容,变成了针对不同页面针对性写爬取规则,比如A页面,有3个ajax用来获取渲染数据,那么就要对于爬取A页面的爬虫,就要再写3个针对ajax的数据爬取

而当需要爬取的页面越来越多的时候,如何能提升效率呢?

于是,针对页面的解析工作,就交给了一些浏览器核去处理了,Phantomjs就是一个基于webkit的js api,能够实现浏览器的功能,这样我们将一个页面输入给Phantomjs,其就如同一个浏览器一样,去解析执行这个页面,获取最终展示的结果。

这两种方式各有优缺点:

  • 针对页面写特定爬虫,准确,执行效率快,维护性差,一旦页面接口变动则需要根据变动修改爬虫
  • Phantomjs通用性高,不需要针对特定页面去写,但执行速度慢(相当于浏览器访问页面了,其所有网络访问都渲染完成了才结束)

那么如何使用Phantomjs呢?

首先是环境,其官网为http://phantomjs.org

推荐使用docker来pull一个镜像,环境都配好了,省事,我使用的是 wernight/phantomjs 这个镜像

下面我们来写个测试页面:

/uploads/2018/01/WX20180131-170814@2x.png

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>一个JS渲染的页面</title>
    </head>
<body></body>
<script>
    document.body.innerHTML = "<p>Your can see me if your are not spider.</p>";
</script>
</html>

很简单的一个页面,其会在页面生成一句 **Your can see me if your are not spider. **

构建一个自己的PHP框架(二)—— 底层搭建之单例模式

好了,上一篇文章我们划分了目录结构,这篇我们将底层设计出来

PHP作为一个脚本语言,其关闭后释放的特性,因此对于每次运行来说,我们如果重复使用的东西,一般都会采用单例模式,这样可以在一次脚本执行过程中,让每一个使用到的对象、变量等做到一次声明多次使用并保证其维持运行状态

一个简单的单例模式就是使用一个全局的对象来存储所有用到的对象或变量

比如,我声明一个注册类,用于存储所有注册的变量、对象

class Registry
{
    private static $instanceList = [];

    public static function set($name, $value)
    {
        self::$instanceList[$name] = $value;
    }

    public static function get($name, $default = null)
    {
        return self::$instanceList[$name] ?? $default;
    }

    public static function exists($name)
    {
        return isset(self::$instanceList[$name]);
    }

    public static function del($name)
    {
        unset(self::$instanceList[$name]);
    }
}

这样一个简单的注册类就完成了,使用的时候,只要使用

Registry::set("hello", "hello world");`

来注册,需要的时候使用

Registry::get("hello"); //hello world`

来获取就可以了

nginx因POST数据过大,报500错误

今天在部署docker的一个nginx服务时候,发现当POST过来数据太大时,会出现一个500的网络错误,打开nginx日志,显示的是对目录访问权限不够,因此进入docker内部,将lib下的nginx给予755权限即可,因为是使用的轻量版的docker容器,无法进入内部,所以使用docker exec即可,命令如下docker exec -it nginxserver chmod -R 755 /var/lib/nginx

Phalcon学习记录(一)

Phalcon\Di 为一个容器里,用于服务的依赖注入,Di类本身只提供了注入功能,并不会默认绑定服务

Phalcon\Di\FactoryDefault 为一个默认容器类,其为Di的子类,会默认注入mvc使用的大部分服务

Phalcon\Di\FactoryDefault\Cli 与FactoryDefault相同,只不过默认只注入了一些用于Cli模式的服务

use Phalcon\Di;
/**
 * 此处也可以根据使用情景使用不同的Di,比如:
 * use Phalcon\Di\FactoryDefault as Di; 使用FactoryDefault作为Di
 * use Phalcon\Di\FactoryDefault\Cli as Di; 使用Cli作为Di
 */
// 声明一个Di的实例
$di = new Di();
/**
 * 定义一个Test类,作为后面做服务的测试
 */
class Test
{
    private $id;
    private $num1;
    private $num2;

    public function __construct($num1 = 0, $num2 = 0)
    {
        // 随机生成id的值,这样以便后面观察单例模式
        $this->id = rand(0, 99999);
        $this->num1 = $num1;
        $this->num2 = $num2;
    }
    
    public function setNum1($num1)
    {
        $this->num1 = $num1;
    }

    public function setNum2($num2)
    {
        $this->num2 = $num2;
    }
}

// 注册一个名为test的服务,使用匿名函数方式
$test_service = $di->set('test', function ($num1, $num2) {
    return new Test($num1, $num2);
});

// 使用数组方式注册一个服务,使用构造方式注入值
$test_service = $di->set('test', [
    'className' => 'Test',
    'arguments' => [
        [
            'type' => 'parameter',
            'value' => 10
        ],
        [
            'type' => 'parameter',
            'value' => 15
        ]
    ]
]);

// 使用数组方式注册一个服务,使用赋值方式注入值
$test_service = $di->set('test', [
    'className' => 'Test',
    'calls' => [
        [
            'method' => 'setNum1',
            'arguments' => [
                [
                    'type' => 'parameter',
                    'value' => 11
                ]
            ]
        ],
        [
            'method' => 'setNum2',
            'arguments' => [
                [
                    'type' => 'parameter',
                    'value' => 13
                ]
            ]
        ]
    ]
]);

// 可以观察到test_service为一个Phalcon\Di\Service的实例
var_dump($test_service);

// 可以使用两种方式来获取刚刚注册的test类实例
// 第一种,使用Di来获取,可以用下面几种方式
$di->get('test', [3, 4]);
$di->getTest(3, 4);

// 使用数组方式时注册的匿名函数不能有参数
$di['test'];

// 使用getService方式注册的匿名函数不能带有参数
$di->getService('test');

// 使用刚刚生成的test_service来获取实例
$test_service->resolve();

// 可以看到上面每个生成的test类的id都不一样。说明每个test类的实例都是重新生成的
// 作为服务,可能大部分时候都是使用单例模式,那么就需要使用setShared来注册服务。
$di->setShared('test', function () {
    return new Test();
});

docker部署时在centos7中遇到的挂载时权限问题

今天在一台centos7部署docker的一个mysql镜像,做配置和数据库的文件挂载,可是怎么都不行,每次使用docker logs 查看都是提示的权限问题,经过反复查找资料,原来是centos7种的selinux将权限给禁掉了

具体解决方法有几种:

  1. 最简单的方法,直接在生成docker容器时,加入参数 --privileged=true 来增加特权

  2. 将挂在的目录添加到selinux的规则中

比如挂在目录为 /app 则使用 chcon -Rt svirt_sandbox_file_t /app

  1. 临时关闭掉selinux

关闭命令:su -c "setenforce 0"

在创建docker后再次开启使用命令:su -c "setenforce 1"