mysql 安装错误记录

存放路径: /opt/mysql/xxx -> /usr/local/mysql

Datadir: /data/mysql/项目_prot/{data,logs,tmp}

配置文件:/etc/my.cnf

手动安装mysql真的遇到了很多问题

Starting MySQL....... ERROR! The server quit without updating PID file (/var/lib/mysql/localhost.loc

尤其是一些参数配置

主要有以下几个文件

/etc/my.cnf
/etc/my.cnf.d/mysql-clients.cnf
/etc/init.d/mysql

总结一下错误

主要还是配置好各个路径以及权限

mysql涉及到的目录都要chown给mysql:mysql

WYTJ9VV%PSI(GCM)$4B%7OG.png

HH]]{B38J_1N9B{FQ@706BH.png

7TST2U}[[O`OUZBTLFA}5JV.png

Laravel 5.0 之 表单验证类 (Form Requests)

让人头痛的表单验证

本文译自 Matt Stauffer 的 系列文章 .

只要你曾经在使用 Laravel 框架的过程中试图找到有关用户输入验证的最佳实践, 你就应该了解这是一个争论最多并且几乎没有达成共识的话题. 我们可以在控制器中进行验证, 可以在单独的一个服务层进行验证, 可以在模型中进行验证, 当然还可以在 Javascript 中进行验证 (这只是一个玩笑, 谁都知道不能只依赖于客户端的验证). 但是, 哪一种做法才是最佳的呢?

Laravel 5.0 新引入的表单请求 (Form Request) 特性提供了集规范性 (差不多就是 "最佳实践" 的意思) 和便捷性 (这是比之前任何一种选择都更强大也更便捷的方式) 于一体的, 在 Laravel 中执行数据检查和验证的新手段.

说明: 本文中使用新的 view() 辅助方法代替了旧版本中的 View::make() .

Form Requests 使表单验证不再让人头痛

Laravel 5.0 带来了 Form Requests, 这是一种特殊的类型, 用于在提交表单时进行数据的检查和验证. 每个 Form Request 类至少包含一个 rules() 方法, 这个方法返回一组验证规则. 除此之外还必须包含一个 authorize() 方法, 该方法返回一个布尔值, 代表是否允许用户执行本次请求.

Laravel 会在解析 POST 路由之前自动把用户输入的信息传递给相应的表单请求, 因此我们的所有验证逻辑都可以移到独立于控制器和模型之外的 FormRequest 对象中.

开始实践: 快速创建一个 Laravel 5.0 项目

如果你还没有创建好的 Laravel 5.0 项目, 用下面的命令创建一个:

$ composer create-project laravel/laravel myProject dev-develop --prefer-dist

1. 添加路由

// app/Http/routes.phpRoute::get('/', 'FriendsController@getAddFriend');Route::post('/', 'FriendsController@postAddFriend');

2. 创建控制器

//app/Http/Controllers/FriendsController:namespace App\Http\Controllers;use App\Http\Requests\FriendFormRequest;use Illuminate\Routing\Controller;use Response;use View;class FriendsController extends Controller{	public function getAddFriend()
	{		return view('friends.add');
	}	public function postAddFriend(FriendFormRequest $request)
	{		return Response::make('Friend added!');
	}
}

3. 创建视图

<html><body>
	@foreach ($errors->all() as $error)		<p class="error">{{ $error }}</p>
	@endforeach	<form method="post">
		<label>First name</label><input name="first_name"><br>
		<label>Email address</label><input name="email_address"><br>
		<input type="submit">
	</form></body></html>

4. 创建 FormRequest

// app/http/requests/FriendFormRequest.phpnamespace App\Http\Requests;use Illuminate\Foundation\Http\FormRequest;use Response;class FriendFormRequest extends FormRequest{	public function rules()
	{		return [			'first_name' => 'required',			'email_address' => 'required|email'
		];
	}	public function authorize()
	{		// 只允许登陆用户
		// 返回 \Auth::check();
		// 允许所有用户登入
		return true;
	}	// 可选: 重写基类方法
	public function forbiddenResponse()
	{		// 这个是可选的, 当认证失败时返回自定义的 HTTP 响应. 
		// (框架默认的行为是带着错误信息返回到起始页面)
		// 可以返回 Response 实例, 视图, 重定向或其它信息
		return Response::make('Permission denied foo!', 403);
	}	// 可选: 重写基类方法
	public function response()
	{		// 如果需要自定义在验证失败时的行为, 可以重写这个方法
		// 了解有关基类中这个方法的默认行为,可以查看:
		// https://github.com/laravel/framework/blob/master/src/Illuminate/Foundation/Http/FormRequest.php
	}
}

接下来, 用 php artisan serve 或者你自己喜欢的方式启动服务器. 提交表单, 你可以看到我们并没有往控制器中添加任何一行验证逻辑, 但是验证规则已经生效了.

其它用例

如果对 "新增" 和 "编辑" 有不同的规则, 或者根据不同的输入进行不同的验证, 要怎么办呢? 这里有几个可以参考的例子, 虽然还不能确定这些就是 "最佳实践":

采用分开的 form requests

Laravel 并没有规定你不能对 "新增" 和 "编辑" 操作采用不同的 form request 类. 所以你可以创建一个包含所有规则的 FriendFormRequest 作为基类, 然后把它扩展为 addFriendFormRequest 和 editFriendFormRequest 两个子类, 每个子类都可以实现各自的默认行为.

采用条件判断逻辑

rules() 作为一个方法而不是属性, 带来的好处就是你可以在方法中添加判断逻辑:

...class UserFormRequest extends FormRequest{
	...	protected $rules = [	
		'email_address' => 'required',		'password' => 'required|min:8',
	];	public function rules()
	{
		$rules = $this->rules;		// 根据不同的情况, 添加不同的验证规则
		if ($someTestVariableShowingThisIsLoginInsteadOfSignup)
		{
			$rules['password'] = 'min:8';
		}		return $rules;
	}
}

也可以在 authorize 方法中添加逻辑, 比如:

...class FriendFormRequest extends FormRequest{
	...	public function authorize()
	{		if ( ! Auth::check() )
		{			return false;
		}
		$thingBeingEdited = Thing::find(Input::get('thingId'));		// 如果是编辑操作, 或者当前用户不是对象创建者
		if ( ! $thingBeingEdited || $thingBeingEdited->owner != Auth::id()) {			return false;
		}		return true;
	}
}

自定义校验

除了上面的方式, 如果需要对验证逻辑进行更深入的控制, 可以重写提供校验对象实例的方法. 下面是一个简单的实例, 后续会专门写一篇文章来解释:

...class FriendFormRequest extends FormRequest{	public function validator(ValidationService $service)
	{
		$validator = $service->getValidator($this->input());		// 可选: 通过新的 ->after() 方法来进行自定义
		$validator->after(function() use ($validator)) {			// 在这里可以做更多更深入的校验
			$validator->errors()->add('field', 'new error);
		}
	}
}

ValidatesWhenResolved 接口

后续还会有一篇有关 ValidatesWhenResolved 接口的文章, 不过那篇文章重点讨论的是对方法/路由等的校验. IOC 何时提供什么东西, 这个在 Laravel 5.0 版已经分离出一个单独的接口. 官方文档: https://github.com/illuminate/contracts/blob/master/Validation/ValidatesWhenResolved.php

其它可自定义的参数:

$redirect : 校验失败时要重定向到的 URI. $redirectRoute : 校验失败时要重定向到的路由.$redirectAction : 校验失败时要重定向到的方法. $dontFlash : 重定向时不要传递的输入项的键 (默认值: ['password', 'password_confirmation']).

写在最后

通过文本可以看到, Form Requests 对于简化表单请求的数据校验是非常强大和方便的. 如果你阅读本文觉得还不够, 可以观看关于 Form Request 的 这个视频 .

本文写作时, Laravel 5.0 还未正式发布, 因此上述内容最终可能还会有修改, 或者作者遗漏了某些东西. 如果你有建议或者对文章内容的修正, 可以在 给译者发邮件 或者(在 Twitter 上直接联系原作者)

[http://twitter.com/stauffermatt].

Service Provider 测试实例

简单归纳一下

1、服务类继承契约接口(为了对类的定义加以约束)

2、创建服务提供者(Service Provider)

3、在服务提供者的register内绑定服务类

4、注册服务提供者到config

5、创建服务容器(Service Container

6、将服务提供者依赖注入服务容器

7、服务容器使用该服务

1、定义服务类

有了上一节有关服务容器的讲述,理解起服务提供者来很简单。我们这里先定义一个绑定到容器的测试类TestService,为了对类的定义加以约束,我们同时还定义一个契约接口TestContract。

定义TestContract如下:

<?php

namespace App\Contracts;

interface TestContract
{
    public function callMe($controller);
}

定义TestService如下:

<?php

namespace App\Services;

use App\Contracts\TestContract;

class TestService implements TestContract
{
    public function callMe($controller)
    {
        dd('Call Me From TestServiceProvider In '.$controller);
    }
}

2、创建服务提供者

接下来我们定义一个服务提供者TestServiceProvider用于注册该类到容器。创建服务提供者可以使用如下Artisan命令:

php artisan make:provider TestServiceProvider

该命令会在app/Providers目录下生成一个TestServiceProvider.php文件,我们编辑该文件内容如下:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\TestService;

class TestServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     * @author LaravelAcademy.org
     */
    public function register()
    {
        //使用singleton绑定单例
        $this->app->singleton('test',function(){
            return new TestService();
        });

        //使用bind绑定实例到接口以便依赖注入
        $this->app->bind('App\Contracts\TestContract',function(){
            return new TestService();
        });
    }
}

可以看到我们使用了两种绑定方法,更多绑定方法参考服务容器文档。

3、注册服务提供者

定义完服务提供者类后,接下来我们需要将该服务提供者注册到应用中,很简单,只需将该类追加到配置文件config/app.php的providers数组中即可:

'providers' => [

    //其他服务提供者

    App\Providers\TestServiceProvider::class,
],

4、测试服务提供者

这样我们就可以在应用中使用该服务提供者了,为了测试该服务提供者我们首先使用Artisan命令创建一个资源控制器TestController:

php artisan make:controller TestController

然后在路由配置文件routes.php中定义路由:

Route::resource('test','TestController');

最后去TestController中编写测试代码:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use App;
use App\Contracts\TestContract;

class TestController extends Controller
{
    //依赖注入
    public function __construct(TestContract $test){
        $this->test = $test;
    }

    /**
     * Display a listing of the resource.
     *
     * @return Response
     * @author LaravelAcademy.org
     */
    public function index()
    {
        // $test = App::make('test');
        // $test->callMe('TestController');
        $this->test->callMe('TestController');
    }

    ...//其他控制器动作
}

然后我们去浏览器中访问http://laravel.app:8000/test

分别测试使用App::make和依赖注入解析绑定类调用callMe方法的输出,结果一样,都是:

"Call Me From TestServiceProvider In TestController"

好了,大功告成,是不是很简单?!

此外,Laravel服务提供者还支持延迟加载,具体可参考服务提供者文档

控制反转(DI) 依赖注入(IoC)

<?php
Class Fight{
    public function __construct($options){
        //...
    }
}

Class Force{
    public function __construct($options){
        //...
    }
}


Class Shot{
    public function __construct($options){
        //...
    }
}

//超能力工厂类
Class SuperModuleFactory{
    public function makeModule($moduleName, $options){
        switch($moduleName){
            case 'Fight':
                return new Fight($options[0], $options[1]);
            case 'Force':
                return new Force($options[0]);
            case 'Shot':
                return new Shot($options[0], $options[1], $options[2]);
            // case 'more': .......
            // case 'and more': .......
            // case 'and more': .......
            // case 'oh no! its too many!': .......
        }
    }
}

Class Superman{
    protected $power;

    public function __construct(array $modules)
    {
        //初始化工厂
        $factory = new SuperModuleFactory;

        //通过工厂提供的方法制造需要的模块
//        $this->power = $factory->makeModule('Fight',[9,100]);
//        $this->power = $factory->makeModule('Force',[50]);
//        $this->power = $factory->makeModule('Shot',[99,150,20]);

        /*
        $this->power = array(
            $factory->makeModule('Force',[45]),
            $factory->makeModule('Shot',[99,40,10])
        );
        */

        //通过工厂提供的方法制造需要的模块
        foreach($modules as $moduleName => $moduleOptions){
            $this->power[] = $factory->makeModule($moduleName, $moduleOptions);
        }

    }
}

//创建超人
$superman = new Superman([
    'Fight' => [9, 100],
    'Shot' => [99, 50, 2]
]);
//“超人”的创建不再依赖任何一个“超能力”的类,如果修改了或者增加了新的超能力只需要针对修改SuperModuleFactory即可。




?>

<?php
//当超能力急需拓展的时候,如果依赖超能力工厂就会在switch里堆很多东西,我们需要制定统一接口作为一种“契约”,这样无论是谁创建出的模组,都符合这样的接口,就可以被正常使用。
interface SuperModuleInterface{
    /**
     * 超能力激活方法
     *
     * 任何一个超能力都得有该方法,并拥有一个参数
     *@param array $target 针对目标,可以是一个或多个,自己或他人
     */
    public function activate(array $target);
}

/**
 * X-超能量
 */
class XPower implements SuperModuleInterface{
    public function activate(array $target){
        // 这只是个例子。。具体自行脑补
    }
}

/**
 * 终极炸弹 (就这么俗)
 */
class UltraBomb implements SuperModuleInterface{
    public function activate(array $target){
        // 这只是个例子。。具体自行脑补
    }
}

//提供的模组实例必须是一个SuperModuleInterface接口的实现
//正是由于超人的创造变得容易,一个超人也就不需要太多的超能力,我们可以创造多个超人,并分别注入需要的超能力模组即可。
//开头到现在提到的一系列依赖,只要不是由内部生产(比如初始化、构造函数 __construct 中通过工厂方法、自行手动 new 的),而是由外部以参数或其他形式注入的,都属于依赖注入(DI)
class Superman{
    protected $module;

    public function __construct(SuperModuleInterface $module)
    {
        $this->module = $module;
    }
}

//下面就是一个典型的依赖注入

//超能力模组
$superModule = new XPower;
//初始化一个超人,并注入一个超能力模组依赖
$superMan = new Superman($superModule);




//我们需要自动化 —— 最多一条指令,千军万马来相见
//工厂模式升华 -- IoC容器
class Container{
    protected $binds;
    protected $instance;

    public function bind($abstract, $concrete){
        if($concrete instanceof Closure){
            //instanceof Closure判断$concrete是否是一个闭包
            $this->binds[$abstract] = $concrete;
        }else{
            // instance 方法绑定一个已存在的对象实例到容器,这里不是绑定只是把concrete放到数组里
            $this->instances[$abstract] = $concrete;
        }
    }

    public function make($abstract, $parameters = []){
        if(isset($this->instances[$abstract])){
            //已经是实例的 直接返回
            //实例是已经被初始化过的 所以不需要再传入参数实例化
            return $this->instances[$abstract];
        }

        array_unshift($parameters, $this);

        return call_user_func_array($this->binds[$abstract], $parameters);
    }
}


//创建一个容器(后面称作超级工厂)
$container = new Container;

//向该超级工厂添加超能力模组的生产脚本
$container->bind('xpower', function($container) {
    return new XPower;
});

//同上
$container->bind('ultrabomb', function($container){
    return new UltraBomb;
});

//向该超级工厂添加超人的生产脚本
$container->bind('superman', function($container, $moduleName){
    return new Superman($container->make($moduleName));
});

//绑定后的XPower以及UltraBomb等超能力 使用$container->make()就可以返回实例
//$container->make('superman','xpower')可以实例化superman注入xpower的实例
//因为superman bind的时候闭包实现了对第二个参数(moduleName)的实例化
//所以就可以直接通过超级工厂类穿件superman的实例
//*********************** 华丽丽的分割线 *************************
//开始启动生产
$superman_1 = $container->make('superman','xpower');
$superman_1 = $container->make('superman','ultrabomb');
$superman_1 = $container->make('superman','xpower');
// ...随意添加


//要添加特异功能的参数我觉得应该修改代码如下,当然也需要修改一下前面的XPower类
$container->bind('xpower',function($container, $parameters){
    return new XPower($parameters);
    //然后XPower的构造函数接收参数做相应处理
});

$container->bind('superman', function($container, $moduleName, $parameters){
    return new Superman($container->make($moduleName, $parameters));
});

$superman_x = $container->make('superman','xpower',array(9,50,25));
//代码没有运行过不知道这样可不可行 只是一个思路


//实际上,真正的 IoC 容器更为高级。
//我们现在的例子中,还是需要手动提供超人所需要的模组参数,但真正的 IoC 容器会根据类的依赖需求,自动在注册、绑定的一堆实例中搜寻符合的依赖需求,并自动注入到构造函数参数中去。
//Laravel 框架的服务容器正是这么做的。实现这种功能其实理论上并不麻烦,但我并不会在本文中写出,因为……我懒得写。
?>

http://laravelacademy.org/post/769.html

laravel 学习笔记

这几天纯看文档稍微记点东西吧

路由 RESTful 资源控制器 Route::resource

动词 路径 行为 路由名称

GET /photo 索引 photo.index
GET /photo/create 创建 photo.create
POST /photo 保存 photo.store
GET /photo/{photo} 显示 photo.show
GET /photo/{photo}/edit 编辑 photo.edit
PUT/PATCH /photo/{photo} 更新 photo.update
DELETE /photo/{photo} 删除 photo.destroy


DI 依赖注入

Ioc依赖反转

其实这些概念在angular和之前看设计模式的时候都接触到过

http://www.jianshu.com/p/b7edc9b22b8a

http://blog.leokim.cn/2017/04/18/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%ACdi-%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5ioc/

Service Container, Service Provider,Contracts, Facade

Service Container就是被注入的类,作为容器,在构造函数内被注入,或者使用facade在顶部声明


Service Provider的bind方法

其实就是在Service Prodide里用bind方法来绑定别名,这个地方文档里的鬼例子看着让人着实迷惑

$this->app->bind('post', function ($app) {
 return new App\Models\Post;
});

绑定后就可以直接

$app->make('post')


singleton和bind的区别

它们两个都是返回一个类的实例,不同的是singleton是单例模式,而bind是每次返回一个新的实例。

https://segmentfault.com/a/1190000004388879


修改更新查找MySQL5.7.x的root用户的默认密码

最近新安装了wamp3.0.4里面附带的mysql已经升级到了5.7版本了。

MySQL5.7在性能方面有很大的提升。安装成功之后默认root的密码为空能登录。

但是正常情况下需要给root重新设置新的密码。

对于MySQL5.7版本来说和之前的5.6及以下版本的user表不一样了(user表里面没有了password这个字段了,mysql5.7 中保存密码的字段是 authentication_string)。

直接上命令行。

mysql5.7 中保存密码的字段是 authentication_string
 
//如果你用Navicat的话,先默认密码登录直接执行sql语句
update mysql.user set authentication_string=password("leokim.cn") where User="root" and Host="localhost";
 
flush privileges; 
 
 
//如果你用dos的话--进入到bin目录
cd D:\wamp\bin\mysql\mysql5.7.11\bin
 
//输入mysql 用户名和密码
mysql -u root -p
 
//新开DOS, 输入mysql,出现mysql> 命令标识符 
mysql>update mysql.user set authentication_string=password("www_dodobook_net") where user="root" and Host="localhost"; 
mysql>flush privileges; 
mysql>quit;

如果你忘了密码想找回密码的话,可以参考下面的方法

其实想要重置 5.7 的密码很简单,就一层窗户纸:
1、修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1
这一行配置让 mysqld 启动时不对密码进行验证
2、重启 mysqld 服务:systemctl restart mysqld
3、使用 root 用户登录到 mysql:mysql -u root 
4、切换到mysql数据库,更新 user 表:
update user set authentication_string = password('root'), password_expired = 'N', password_last_changed = now() where user = 'root';
在之前的版本中,密码字段的字段名是 password,5.7版本改为了 authentication_string
5、退出 mysql,编辑 /etc/my.cnf 文件,删除 skip-grant-tables=1 的内容
6、重启 mysqld 服务,再用新密码登录即可.

另外,MySQL 5.7 在初始安装后(CentOS7 操作系统)会生成随机初始密码.

并在 /var/log/mysqld.log 中有记录,可以通过 cat 命令查看,找 password 关键字.

找到密码后,在本机以初始密码登录,并且(也只能)通过命令

alter user 'root'@'localhost' identified by 'root'

修改 root 用户的密码为 root,然后退出,重新以root用户和刚设置的密码进行登录即可。

 

也可以在安装的时候不生成随机密码,用 sudo mysqld –initialize-insecure

然后在自己设置密码 sudo /usr/bin/mysqladmin -uroot password 密码

如果你是之前的版本MySQL5.5 MySQL5.6的话请直接使用以下语句和方法

//先输入密码。默认为空就直接按Enter即可
mysql> use mysql
Database changed
mysql> update user set password=PASSWORD('leokim') where user='root';
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3  Changed: 3  Warnings: 0
  
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
  
mysql> quit

npm-config

npm config set <key> <value> [-g|--global]
npm config get <key>
npm config delete <key>
npm config list
npm config edit
npm get <key>
npm set <key> <value> [-g|--global]

file:///C:/software/nodejs/node_modules/npm/html/doc/cli/npm-config.html

centos7 nginx安装

安装nginx必备软件

yum install -y gcc
yum install -y gcc-c++
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel

修改/etc/sysctl.conf

fs.file-max = 999999 //表示一个进程最多可以打开的文件句柄数
net.ipv4.tcp_tw_reuse = 1 //这个参数设置为1,表示允许将TIME-WAIT状态的socket重新用于新的TCP连接。
net.ipv4.tcp_keepalive_time = 600 //监控对方连接是否正常的心跳发送间隔时间,默认2小时,设置小更快清理无效连接。
net.ipv4.tcp_fin_timeout = 30 //当tcp处于FIN_WAIT_2状态时,socket保持的最长时间
net.ipv4.ip_local_port_range = 1024 61000
net.ipv4.tcp_rmem = 4096 32768 262142
net.ipv4.tcp_wmem = 4096 32768 262142
net.core.netdev_max_backlog = 8096
net.core.rmem_default = 262142
net.core.wmem_default = 262142
net.core.rmem_max = 2097152
net.core.wmem_max = 2097152
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 1024

修改默认运行端口

修改 nginx.conf 文件实现。在 Linux 上该文件的路径为 /usr/local/nginx/conf/nginx.conf,Windows 下 安装目录\conf\nginx.conf。

server {
	listen       81;
	server_name  localhost;
	
	location / {
		root   html;
		index  index.html index.htm;
	}
	……
}

对iptable进行修改

vi /etc/sysconfig/iptables #编辑防火墙配置文件

-A INPUT -m state --state NEW -m tcp -p tcp --dport 81 -j ACCEPT

systemctl restart iptables.service #最后重启防火墙使配置生效
systemctl enable iptables.service #设置防火墙开机启动

启动ngnix

/usr/local/nginx/sbin/ngnix

成功!

blob.png

php 获取月份最后一天

<?php
    echo date("t",strtotime('2016-02'));
?>

常用方法

<?php
echo strtotime("now"), "\n";
echo strtotime("10 September 2000"), "\n";
echo strtotime("+1 day"), "\n";
echo strtotime("+1 week"), "\n";
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo strtotime("next Thursday"), "\n";
echo strtotime("last Monday"), "\n";
?>