0%

梦想使生活得以忍受
### 安装环境 - centos6.8 64 - httpd2.4.25

安装过程

  • 下载httpd

    1
    wget http://apache.fayea.com//httpd/httpd-2.4.25.tar.gz
  • 安装apr

    1
    2
    3
    4
    5
    下载: wget http://mirrors.hust.edu.cn/apache//apr/apr-1.5.2.tar.bz2
    解压,并进入到目录
    执行 ./configure
    默认安装目录: /usr/local/apr
    make make install
  • 安装apr-util

    1
    2
    3
    http://mirrors.hust.edu.cn/apache//apr/apr-util-1.5.4.tar.gz

    ./configure --with-apr=/usr/local/apr (需要指明 apr的安装目录)
  • 安装 pcre

    1
    2
    偷懒安装:
    yum install pcre prce-devel
  • 编译httpd

    1
    2
    3
    ./configure --prefix=/usr/local/httpd --enable-MODULE=shared
    make
    make install

编译完成

  • 基本操作
    ./apachectl restart
    ./apachectl start
    ./apachectl stop

一想到时光匆匆,竟经不起半点挥霍,我就会对时间吝啬起来,因为此刻已过,便永不复还。
Linux系统中,所有用户(包括系统管理员)的账号和密码都可以在/etc/passwd和/etc/shadow这两个文件中找到;

/etc/passwd

通过指令 vi /etc/passwd 打开passwd文件来看看,下面列举部分内容如下:

1
2
3
4
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh

上面每一行都代表一个用户,每一行又通过[:]分为七个部分,下面就说说这七项都代表什么。
  1、账号名称
  2、原先用来保存密码的,现在密码都放在/etc/shadow中,所以这里显示x
  3、UID,也就是使用者ID。默认的系统管理员的UID为0,我们添加用户的时候最好使用1000以上的UID,1-1000范围的UID最好保留给系统用。
  4、GID,也就是群组ID
  5、关于账号的一些说明信息(暂时可以忽略)
  6、账号的家目录,家目录就是你登陆系统后默认的那个目录
  7、账号使用的shell

/etc/shadow

看完/etc/passwd,再来看看/etc/shadow里都有啥?于是在ubuntu的终端中输入 vi /etc/shadow 会出现了下面的错误信息:

“/etc/shadow” [Permission Denied]

忘了ubuntu中默认登陆的不开启root账户,而/etc/shadow文件只有root账户才能够访问,那怎么办呢,只好开启ubunt的root账户了,或者 sudo vi /etc/shadow即可,搞定之后shadow的内容如下面样式:

1
2
3
root:!:15324:0:99999:7:::
daemon:*:15259:0:99999:7:::
bin:*:15259:0:99999:7:::

letuknowit:$1$cPf/cIvr$sCws95uSip2ljTK052DDB.:15400:5:60:7:2:15490:
这里也是由[:]来进行分割,但是这里一共分出来九个栏目,每个栏目的解释如下:
  1、账户名称(密码需要与账户对应的嘛)
  2、加密后的密码(总不能学CSDN放明文密码,是吧),如果这一栏的第一个字符为!或者*的话,说明这是一个不能登录的账户,从上面可以看出,ubuntu默认的就不启用root账户。
  3、最近改动密码的日期(不是日期吗,咋是一堆数字,别急,这个是从1970年1月1日算起的总的天数)。那怎么才能知道今天距1970年1月1日有多少天呢?很简单,你改下密码,然后看下这个栏目中的数字是多少就可以了!
  4、密码不可被变更的天数:设置了这个值,则表示从变更密码的日期算起,多少天内无法再次修改密码,如果是0的话,则没有限制
  5、密码需要重新变更的天数:密码经常更换才能保证安全,为了提醒某些经常不更换密码的用户,可以设置一个天数,强制让用户更换密码,也就是说该用户的密码会在多少天后过期,如果为99999则没有限制
  6、密码过期预警天数:如果在5中设置了密码需要重新变更的天数,则会在密码过期的前多少天进行提醒,提示用户其密码将在多少天后过期
  7、密码过期的宽恕时间:如果在5中设置的日期过后,用户仍然没有修改密码,则该用户还可以继续使用的天数
  8、账号失效日期,过了这个日期账号就不能用了
  9、保留的

我先起,你再睡一会儿。
一:提问前一定要搜索,先在 Google 搜索,然后在 StackOverFlow 上搜索,当实在找不到答案后再提问。 对于那些靠搜索就能得到答案的问题,StackOverFlow 上的广大群众是毫不留情的,反对票数量蹭蹭得往上加啊。 二:学习一些典型的提问/回答习惯,我做了一些笔记。

提问:

  • 1,In my limited experience with .. 谦虚表达自己在某方面的经验
  • 2, I am searching for a long time on net. But no use. Please help or try to give some ideas how to achieve this. 找了很久未果,求助攻
  • 3,after searching around for a decent XX solution and found that everything out there was difficult to use. 找了N种方法都发现太TM难了。
  • 4,I’ ve looked around and apparently I’ve got the choice between these libraries/ solutions: 说明自己是努力搜索过的,然后目前有了哪几种方案
  • 5,which seems it’s a promising solution. 看起来是一个好解决方案
  • 6,Ive tried multiple variations of this, but none of them seem to work. Any ideas? 试了很多种方法都无效,求助
  • 7,Wanted to know if it’s good practice to do that and what would be the best way to do that? 我的做法是否正确,是否有更好的法子?
  • 8,Thanks in advance.

先行谢过回答问题:

  • 1,If I understand you correctly, you want to xxx 如果我没理解错,你想。
  • 2,Can you provided more details about your use case ? Can you provide more xml and code setting the url ?

提供更详细当别人回答你的问题后,你对回答的评论:

  • 1,thank you for your answer sincerely 感谢回答blabla这些感觉就差不多了,其他说来说去也都是这些套路,回答问题或者提问时多看看别人的表达习惯,也可以做记录,好记性不如烂笔头嘛。说明一下,上面的中文不是翻译,只是一个说明,方便我快速定位的。

我只说从今往后,不说今日以前。
Let’s imagine the situation: you have a big database table (like 10 000 rows or bigger) and you need to run an update to one column. But you cannot run just SQL query – there is some PHP logic behind it. So foreach loop could potentially take forever or bump into a default 30-second script limit. Luckily, Laravel has a neat solution for it.

Let’s look at a simple example of a problem I’m talking about:

1
2
3
4
5
6
$users = User::all();
foreach ($users as $user) {
$some_value = ($user->some_field > 0) ? 1 : 0;
// might be more logic here
$user->update(['some_other_field' => $some_value]);
}

Do you see the problem? It’s fine for a DB table with 100 or 500 users. But what about 10000? 100000? Million?
It’s not only about the speed, but also about storing the data – you are potentially storing the whole database table into variables, you might run out of memory.

So here’s the thing: there is a function called chunk() which splits all data into separate selects, like pagination.
Let’s look at an example:

1
2
3
4
5
6
7
User::chunk(100, function ($users) {
foreach ($users as $user) {
$some_value = ($user->some_field > 0) ? 1 : 0;
// might be more logic here
$user->update(['some_other_field' => $some_value]);
}
});

http://www.jianshu.com/p/5dafd0d6e69a

女人容颜逝去要十年,男人贬值不过一瞬间。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import sys
import os

from bs4 import BeautifulSoup
import markdown


class MarkdownToHtml:

headTag = '<head><meta charset="utf-8" /></head>'

def __init__(self, cssFilePath = None):
if cssFilePath != None:
self.genStyle(cssFilePath)

def genStyle(self,cssFilePath):
with open(cssFilePath,'r') as f:
cssString = f.read()
self.headTag = self.headTag[:-7] + '<style type="text/css">{}</style>'.format(cssString) + self.headTag[-7:]

def markdownToHtml(self,**arguments):
if 'sourceFilePath' in arguments:
sourceFilePath = arguments['sourceFilePath']
else:
return
if 'destinationDirectory' in arguments:
destinationDirectory = arguments['destinationDirectory']
else:
# 未定义输出目录则将源文件目录(注意要转换为绝对路径)作为输出目录
destinationDirectory = os.path.dirname(os.path.abspath(sourceFilePath))
if 'outputFileName' in arguments:
outputFileName = arguments['outputFileName']
else:
# 未定义输出文件名则沿用输入文件名
outputFileName = os.path.splitext(os.path.basename(sourceFilePath))[0] + '.html'
if destinationDirectory[-1] != '/':
destinationDirectory += '/'
with open(sourceFilePath,'r', encoding='utf8') as f:
markdownText = f.read()
# 编译出原始 HTML 文本
rawHtml = self.headTag + markdown.markdown(markdownText,output_format='html5')
# 格式化 HTML 文本为可读性更强的格式
beautifyHtml = BeautifulSoup(rawHtml,'html5lib').prettify()
with open(destinationDirectory + outputFileName, 'w', encoding='utf8') as f:
f.write(beautifyHtml)

if __name__ == "__main__":
mth = MarkdownToHtml()
# 做一个命令行参数列表的浅拷贝,不包含脚本文件名
argv = sys.argv[1:]
# 目前列表 argv 可能包含源文件路径之外的元素(即选项信息)
# 程序最后遍历列表 argv 进行编译 markdown 时,列表中的元素必须全部是源文件路径
if '-s' in argv:
cssArgIndex = argv.index('-s') +1
cssFilePath = argv[cssArgIndex]
# 检测样式表文件路径是否有效
if not os.path.isfile(cssFilePath):
print('Invalid Path: ' + cssFilePath)
sys.exit()
mth.genStyle(cssFilePath)
# POP顺序不能随意变化
argv.pop(cssArgIndex)
argv.pop(cssArgIndex-1)
if '-o' in argv:
dirArgIndex = argv.index('-o') +1
outputDirectory = argv[dirArgIndex]
# 检测输出目录是否有效
if not os.path.isdir(outputDirectory):
print('Invalid Directory: ' + outputDirectory)
sys.exit()
# POP顺序不能随意变化
argv.pop(dirArgIndex)
argv.pop(dirArgIndex-1)
argumentsList = [dict([('sourceFilePath',filePath), ('destinationDirectory',outputDirectory)]) for filePath in argv]
else:
argumentsList = [dict([('sourceFilePath',filePath)]) for filePath in argv]
# 至此,列表 argv 中的元素均是源文件路径
for argument in argumentsList:
# 检测文件路径是否有效
if os.path.isfile(argument['sourceFilePath']):
mth.markdownToHtml(**argument)
else:
print('Invalid Path: '+argument['sourceFilePath'])

你为什么从事喜剧行业?人们总是嘲笑我,所以我想,去他妈的,干脆收他们点儿钱!
Laravel facades 就是服务容器里那些基类的「静态代理」,相比于传统的静态方法调用,facades 在提供更简洁且丰富的语法的同时,还有更好的可测试性和扩展性。

所有的 Laravel facades 都在 Illuminate\Support\Facades 这个命名空间下。所以我们可以用类似下面的代码轻松调用:

1
2
3
4
5
use Illuminate\Support\Facades\Cache;

Route::get('/cache', function () {
return Cache::get('key');
});

使用注意

使用 facades 最主要的风险就是会引起类的体积的膨胀。由于 facades 使用起来非常简单而且不需要注入,我们会不经意间在单个类中大量使用。不像是使用依赖注入,用得越多,构造方法会越长,在视觉上就会引起注意,提醒你这个类有点太庞大了。所以,在使用 facades 时,要特别注意把类的体积控制在一个合理的范围。
在开发第三方扩展包时,如果需要使用和 Laravel 交互的扩展包,最好是注入 Laravel contracts 而不是使用 facades,因为扩展包不是在 Laravel 内部使用的,无法使用 Laravel 的 facades 的测试辅助函数。

Laravel contracts

Laravel 中的 Contract 是一组定义了框架核心服务的接口。例如,Illuminate\Contracts\Queue\Queue contract 定义了实现队列任务所需实现的方法,而 Illuminate\Contracts\Mail\Mailer contract 定义了发送邮件所需要实现的方法。

框架为每个 contract 都提供了一个相对应的实现。例如,Laravel 为队列提供了各种驱动的实现,以及基于 SwiftMailer 对邮件功能的实现。

岁月不饶人,我亦未曾饶过岁月。
避免在模板中使用过多的复杂的判断,@inject 的用法

新建文件 app\Presenters\UserPresenter.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
namespace App\Presenters;

class UserPresenter
{
public function setName($name)
{
if ($name == 'Laurine Deckow')
$fullName = 'Mr. ' . $name;
else
$fullName = 'Mrs. ' . $name;

return $fullName;
}
}

控制器 app\Http\Controllers\UserController.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

namespace App\Http\Controllers;

use App\User;

class UserController extends Controller
{

public function getUser()
{
$users = User::all();
return view('home/user',['users'=>$users]);
}
}

视图 resources\views\home\user.blade.php

1
2
3
4
5
6
7
8
<ul class="list-group">
@inject('UserPresenter','App\Presenters\UserPresenter')
@foreach($users as $user)
<li class="list-group-item">
{{ $UserPresenter->setName($user->name) }}
</li>
@endforeach
</ul>

孤独到死是一个天才最好的归宿,毕竟,这个世界配不上他

中大型架构

解决我们的控制器,模型过于肥大的问题
那么我们应该怎么写呢?别将我们的思维局限在 MVC 內 :

  • Model : 被当成 Eloquent class。
  • Repository : 辅助 model,处理资料库逻辑,然后注入到 service。
  • Service : 辅助 controller,处理商业逻辑,然后注入到 controller。
  • Controller : 接收 HTTP request,调用其他 service。
  • Presenter : 处理展示逻辑,然后注入到 view。
  • View : 使用 blade 将资料 binding 到 HTML。

实现结果

我们可以发现 MVC 架构还在,由于 SOLID 的单一职责原则与依赖翻转原则 :

我们将资料库逻辑从 model 分离出来,由 repository 辅助 model,将 model 依赖注入进 repository。
我们将商业逻辑从 controller 分离出来,由 service 辅助 controller,将 service 依赖注入进 controller。
我们将演示逻辑从 view 分离出来,由 presenter 辅助 view,将 presenter 依赖注入进 view。

忠告

  1. 别害怕建立目录
  2. 文件单一职责原则
  3. 在 app 目录下建立 Repositories,Services , Presenters 目錄。

详细链接

  1. 如何使用Repository模式
  2. 如何使用Presenter模式
  3. 如何使用Service模式
  4. laravel的中大型架构

http://oomusou.io/laravel/laravel-architecture

某天,你无端想起一个人,她曾让你对明天有所期许,但是却完全没有出现在你的明天里。
这里我们介绍一种laravel开发的模式,用于解决控制器过于肥大的问题.

路由 routes.php

1
2
<?php
Route::get('/user', 'UserController@getUser');

控制器 app\Http\Controllers\UserController.php

将新建的库依赖注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

namespace App\Http\Controllers;

use App\Repository\UserRepository;

class UserController extends Controller
{
protected $userRepository;

public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}

public function getUser()
{
return $this->userRepository->getUser();
}
}

模型 app\User.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];

/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}

新建库 app\Repository\UserRepository.php

将模型依赖注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php namespace App\Repository;

use App\User;

class UserRepository
{
protected $user;

public function __construct(User $user)
{
$this->user = $user;
}

public function getUser()
{
return $this->user->all();
}

}

最大的痛苦,不是失败,是我本可以。

什么是语义化?其实简单说来就是让机器可以读懂内容。先随便扯扯。对于当前的 Web 而言,HTML 是联系大多数 Web 资源的纽带,也是内容的载体。在 Web 被刚刚设计出来的时候,Tim Berners-Lee 可能不会想到它现在会达到的规模以及深入到我们生活的那么多方面。也许起初的想法很简单:用来发布 Web 内容和资源的索引,方便人们查看。但是随着 Web 规模的不断扩大,信息量之大已经不在人肉处理的范围之内了。这个时候人们开始用机器来处理 Web 上发布的各种内容,搜索引擎就诞生了。再后来,人们又设计了各种智能程序来对索引好的内容作各种处理和挖掘。所以让机器能够更好地读懂 Web 上发布的各种内容就变得越来越重要。其实 HTML 在刚开始设计出来的时候就是带有一定的「语义」的,包括段落、表格、图片、标题等等,但这些更多地只是方便浏览器等 UA 对它们作合适的处理。但逐渐地,机器也要借助 HTML 提供的语义以及自然语言处理的手段来「读懂」它们从网上获取的 HTML 文档,但它们无法读懂例如「红色的文字」或者是深度嵌套的表格布局中内容的含义,因为太多已有的内容都是专门为了可视化的浏览器设计的。面对这种情况,出现了两种观点:我们可以让机器的理解能力越来越接近人类,人能看懂、听懂的东西,机器也能理解;我们应该在发布内容的时候,就用机器可读的、被广泛认可的语义信息来描述内容,来降低机器处理 Web 内容的难度(HTML 本身就已经是朝这个方向迈出的一小步了)。
内容的语义表达能力和 AI 的智能程度决定了机器分析处理 Web 内容能力的高低。上面观点 1 的方向是朝着人类水平的人工智能努力,而观点 2 的方向正是万维网创始人 Tim Berners-Lee 爵士提出的美好愿景:语义网。语义网我就不多说了,简单来说就是让一切内容和包括对关系的描述都成为 Web 上的资源,都可以由唯一的 URI 定义,语义明确、机器可读。显然,两条路都的终极目标都很遥远,第一条路技术上难以实现,而第二条路实施起来障碍太多。我认为我们当前能够看得见摸得着的 Web 语义化,其实就是在往第二条路的方向上,迈出的一小步,即对已经有的被广泛认可的 HTML 标准做改进。我们刚开始意识到,我们必须回归内容本身,将内容本身的语义合理地表述出来,再为不同的用户代理设计不同的样式描述,也就是我们说的内容与样式分离。这样我们在提供内容的时候,首先要做的就是将内容本身进行合理的描述,暂时不用考虑它的最终呈现会是什么样子。HTML 规范其实一直在往语义化的方向上努力,许多元素、属性在设计的时候,就已经考虑了如何让各种用户代理甚至网络爬虫更好地理解 HTML 文档。HTML5 更是在之前规范的基础上,将所有表现层(presentational)的语义描述都进行了修改或者删除,增加了不少可以表达更丰富语义的元素。为什么这样的语义元素是有意义的?因为它们被广泛认可。所谓语义本身就是对符号的一种共识,被认可的程度越高、范围越广,人们就越可以依赖它实现各种各样的功能。HTML5 并非 Web 语义唯一倚仗的规范,除了 W3C 和 WHATWG 外,还有其它的组织在为扩展、标准化 Web 语义做着贡献。只要有浏览器厂商、搜索引擎原意支持,它们的规范一样可以成为通用的基础设施。例如 microformats 社区以及 http://Schema.org 上都有对 HTML 以及 Microdata(http://www.w3.org/TR/html5/microdata.html) 规范的扩展词汇表,Google、Bing、Yahoo! 等搜索引擎以及各个主流浏览器都不同程度地接纳了其中定义的语义扩展,并应用在了生产中。下面举两个 Google 应用扩展语义的例子。Google 的搜索结果,可以根据 microformats 的 hCard 语法从抓取的页面识别出人物信息:

https://www.zhihu.com/question/20455165