创建自己的 Thinkcmf 后台模板

18 Jul 2018 Category: PHP

由于工作原因,项目的后台都是采用Thinkcmf搭建。但是看了那么久的默认样式,还是觉得有点不喜欢。因此想自己套一套主题上去,弄个漂亮点的界面效果。 经过两天的努力,终于在material-dashboard html后台模板的基础,结合thinkcmf官方bootstrap3 的模板修改出一套material模板。

修改过程比较麻烦的事

  • thinkcmf的所有模板都是以引入的方式,引入header,而没有使用thinkphp的模板继承。这种方式,当需要在全部页面添加一个公共的动东西,比如一个隐藏控件,操作起来比较麻烦,需要修改所有的文件。

  • iframe左侧菜单的输出需要根据模板进行修改,html结构改动比较大。

  • 继承的继承模板创建好之后,需要一个个的去修改原有页面的代码,添加模板继承,将不需要改动的地方放入content block 中

查看更多

Laravel5.6 博客搭建系列三--博客内容增删改查

08 May 2018 Category: PHP

本篇内容分享创建后台博客内容增删改查操作。

创建markdown转html Service

要想实现markdown 到html的转换,需要安装两个依赖库:

composer require michelf/php-markdown
composer require michelf/php-smartypants

在app下创建Services目录,存放相应的服务类文件。在app/Services创建Markdowner.php,实习markdown转html,文件内容如下:

<?php

namespace App\Services;

use Michelf\MarkdownExtra;
use Michelf\SmartyPants;

class Markdowner
{

    public function toHTML($text)
    {
        $text = $this->preTransformText($text);
        $text = MarkdownExtra::defaultTransform($text);
        $text = SmartyPants::defaultTransform($text);
        $text = $this->postTransformText($text);
        return $text;
    }

    protected function preTransformText($text)
    {
        return $text;
    }

    protected function postTransformText($text)
    {
        return $text;
    }
}

查看更多

Laravel5.6 博客搭建系列二--搭建后台管理系统

02 May 2018 Category: PHP

创建用户认证系统

本篇文章跟大家分享搭建后台管理认证系统以及创建后台视图模板

Laravel 中实现登录认证非常简单。实际上,几乎所有东西 Laravel 都已经为你配置好了。配置文件位于 config/auth.php,其中包含了用于调整认证服务行为的、文档友好的选项配置。

执行php artisan make:authphp artisan migrate 创建控制器以及需要的数据表。脚本会在目录app/Http/Auth 下创建一下几个文件:

  • 创建必须的控制器

    • LoginController 登录退出操作,继承App\Http\Controllers\Controller,所有的业务逻辑在trait AuthenticatesUsers中,可以通过设置属性$redirectTo改变登录之后的跳转地址,设置$redirectAfterLogout改变退出之后的跳转地址;

    • RegisterController 提供用户注册相关操作,所有业务逻辑在trait RegistersUsers

    • ForgotPasswordController 忘记密码,发送验证邮件相关操作

    • ResetPasswordController 重置密码相关操作

查看更多

Laravel5.6 博客搭建系列一

24 Apr 2018 Category: PHP

Laravel框架目前已经发展到5.6版本了,但是目前官方的入门教程还是基于5.1的博客教程。为了更多的人能快速上手新版本,本教程使用Laravel5.6 一部一部跟大家分享如何搭建一个博客系统。下面来看一下如何用十分钟使用Laravel5.6搭建简单博客

安装环境

Laravel 框架对PHP版本和扩展有一定要求

  • PHP >= 7.1.3
  • PHP OpenSSL 扩展
  • PHP PDO 扩展
  • PHP Mbstring 扩展
  • PHP Tokenizer 扩展
  • PHP XML 扩展
  • PHP Ctype 扩展
  • PHP JSON 扩展

下载安装PHP7,composer,mysql 执行 composer global require "laravel/installer", 安装laravel之后配置环境变量,执行laravel new blog

查看更多

PHP Workerman 中使用Timer的实现

16 Jan 2018 Category: PHP

Workerman 是由PHP原生开发的常驻内存应用框架。通过Workerman可以实现PHP常驻内存,给PHP更加广泛的应用场景。类似的还有使用C语言开发的PHP扩展 Swoole,也是实现类似的方案。下面来看看Workerman中如何实习定时器Timer。

public static function init($event = null)
{
    if ($event) {
        self::$_event = $event;
    } else {
        pcntl_signal(SIGALRM, array('\Workerman\Lib\Timer', 'signalHandle'), false);
    }
}

/**
 * ALARM signal handler.
 *
 * @return void
 */
public static function signalHandle()
{
    if (!self::$_event) {
        pcntl_alarm(1);
        self::tick();
    }
}

以上就是核心代码,init函数通过参数注入,确定事件处理机制。默认使用pcntl信号处理。signalHandle用于接受信号之后的处理函数。如果设置了事件处理对象,则调用事件处理对象进行处理,否则调用tick方法,对pcntl信号进行处理。从上面代码可以看出,pcntl信号机制,定时每隔一秒触发一次,所以Workerman 的定时器最小精度1s。但是如果使用其他事件处理方式,确实可以达到0.001的精度。

查看更多

PHP 数组函数array_chunk和array_column

13 Jan 2018 Category: PHP

1、array_chunk($array,$size,$is_keep_key);将数组分割为size大小的数组块,如果$is_keep_key则保留原始的key,否则所有key从0开始,并返回一个二维数组。如果size大小不能整除,最后一个就是余数个大小的数组;如果size 大于等于原始数组,则将数组分割成一个数组,并组合成二维数组;

$age=array("P"=>"35","B"=>"37","J"=>"43","K"=>"53");
print_r(array_chunk($age,3,true));

输出内容:

Array
(
    [0] => Array
        (
            [P] => 35
            [B] => 37
            [J] => 43
        )

    [1] => Array
        (
            [K] => 53
        )

)

查看更多

PHP foreach 引用传递 循环之后的事情

03 Jan 2018 Category: PHP

foreach 是PHP语法中最最常用的。foreach可以直接对循环结构进行便利,也可以以引用的方式进行遍历,在遍历的过程修改原来循环结构 今天就来谈谈foreach 以引用的方式,循环之后的一些事情。

  • case 1
$a = [0,1,3,5];
foreach ($a as $key => &$item) {
	echo $item.' ';
}
print_r($a);
$item = 10;
print_r($a);

我们看看上面的代码输出内容:echo: 0 1 3 5

两个print_r的输出内容

(
    [0] => 0
    [1] => 1
    [2] => 3
    [3] => 5
)
Array
(
    [0] => 0
    [1] => 1
    [2] => 3
    [3] => 10
)

从上面可以看出,foreach引用循环之后,$item并没有释放,还是指向数组最后一个元素的引用,所以后续代码中如果使用了一个同名的遍历,将会同时影响到原来的数组。

  • case 2
$a = [0,1,3,5];
foreach ($a as $key => &$item) {
	echo $item.' ';
	if($key>1){
		break;
	}
}
print_r($a);
$item = 10;
print_r($a);

我们看看上面的代码输出内容:echo: 0 1 3 5

两个print_r的输出内容

(
    [0] => 0
    [1] => 1
    [2] => 3
    [3] => 5
)
Array
(
    [0] => 0
    [1] => 1
    [2] => 10
    [3] => 5
)

从以上的输出结果可以看出,$item总是指向循环跳出之前的最后一个元素

  • case 3
$a = [0,1,3,5];
foreach ($a as $key => &$item) {
	echo $item.' ';
}
print_r($a);
foreach($a as $key => $item)
{
	echo $item;
}
print_r($a);

我们看看上面的代码输出内容:echo1: 0 1 3 5,echo2:0 1 3 3

两个print_r的输出内容

(
    [0] => 0
    [1] => 1
    [2] => 3
    [3] => 5
)
Array
(
    [0] => 0
    [1] => 1
    [2] => 3
    [3] => 3
)

这个结果就有点绕,网上有很多说这是PHP foreach 的bug,但是仔细分析,其实并不是bug.我们把第二个循环拆解开:

  1. $t = $a[0]; $item = $t; //此时 $a[3] = $a[0], $a的内容[0,1,3,0]
  2. $t = $a[1]; $item = $t; //此时 $a[3] = $a[1], $a的内容[0,1,3,1]
  3. $t = $a[2]; $item = $t; //此时 $a[3] = $a[2], $a的内容[0,1,3,3]
  4. $t = $a[3]; $item = $t; //此时 $a[3] = $a[3], $a的内容[0,1,3,3]

通过上面三种情况,可以了解到foreach引用传递之后,我们需要unset($item),接触引用,否则一旦循环之后的代码有是有到循环中的变量名,很容易造成bug。由于大型系统并非一个人完成,所以在多人协作的时候,一定要把自己的数据处理干净,避免bug

其他引用相关


$arr = [0,1];
$arr = [&arr];
var_dump($arr === $arr[0]);

以上输出结果是true。因为$arr 和 $arr[0]指向同一个数据地址。

$arr = [0,1];
function test($item,$key,&$arr){
    unset($arr[$key]);
}
array_walk($arr, 'test',$arr);
var_dump($arr);

以上输出内容还是[0,1]。

查看更多

Http中的connection:keep-alive

25 Dec 2017 Category: 基础

http请求中的keep-alive 有什么用,怎么用?

  • http请求

一个典型的http请求:

GET / http/1.1
Host: www.baidu.com
Connection:keep-alive
Catch-control:no-cache
Pragma:no-cache
Accept:*/*
Accept-Language:zh-cn
Accept-encoding:gzip, deflat, br
User-Agent:Chrome/5.0
Cookie:BAIDUID=sksjdjjjjjjjj


t=12&q=222

http属于短连接形式,无状态的。每次请求,建立tcp链接之后从服务器获取数据之后断开tcp链接。再次请求再重复执行上面的操作。

  • keep-alive有什么用

为了尽可能的减少http请求建立的连接数,http协议实现了keep-alive,用于多个http请求复用tcp连接。以往打开网页,需要连续执行十几个http请求需要建立十几个tcp连接,而有了keep-alive之后,十几个http请求通过复用tcp连接,只需要3-8个tcp连接就能实现,具体个数视服务器处理速度而定,客户端请求不是并发请求的时候效果最佳。

对比一下当服务端开启keep-alive支持之前和之后的连续三个http请求数据抓包对比:

未开启keep-alive 3次访问相同也没 tcp请求数据

未开启keep-alive

未开启keep-alive 3次访问相同也没 tcp请求数据

开启keep-alive

从两张图的对比可以知道,开启keep-alive的时候,连续三个http请求复用了同一个tcp连接。而没有开启keep-alive的3次请求,每次请求之后都会断开之前的连接,不会复用。对服务器而言,回尽可能的复用tcp,所以当一个活跃的tcp请求客户端断开之后,服务器端会进入TIME_WAITE状态,因此开启keep-alive也能够减少服务器TIME_WAITE的数目。

  • keep-alive怎么用

虽然keep-alive可以复用tcp连接,但是同时也会长时间挂起这个连接不会释放,等待下次请求复用,等待时间是KeepAliveTimeout, Apache中配置文件的描述:

KeepAliveTimeout: Number of seconds to wait for the next request from the same client on the same connection.

从上面开启keep-alive的截图中可以看出,tcp连接最终的断开时间是在最后一个请求KeepAliveTimeout后都没有新请求过来,服务端就会断开该连接。但是KeepAliveTimeout得时间长短会影响服务器的并发请求数。假设极端情况下KeepAliveTimeout设置为1000s,服务器最大可以建立的tcp连接65535,系统最大支持访问人数限制在65535/1000,即65。因为每个连接占用1000s,服务器在1000s内不会释放该tcp连接,从而导致无法处理新的请求,这种情况如果遇到syn flood攻击的话,会立即崩溃。

所以keep-alive开启,以及超时时间的设置很关键,时间设置的太短,退化成connection:close的情况。时间太长,则会拖垮整个系统。

查看更多