php初心者, 记录自己工作和学习路上的感想和笔记

0%

图片alt

人生第一个自驾游成功达成,很是开心,能跟心爱的人一起出去玩,虽然很累,虽然给小妞坑了,让我俩累的半死,但是依然很开心啊。

话说又是很久没有写东西了,不过还是有理由的,搬家,加班,各种忙。接下来应该会调整一些状态了,而且昨晚想了一下,为什么最近的状态特别不好。

哎呀,很多想说的,不知道怎么说出来,还是回家在总结一下吧。 最后在附上一张图片吧

图片alt

首先创建 Phpstorm.desktop 文件,并把下面的代码输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Desktop Entry]
Categories=Development;
Comment[zh_CN]=
Comment=
Exec=/opt/phpstorm/bin/phpstorm.sh
GenericName[zh_CN]=IDE
GenericName=IDE
Icon=/opt/phpstorm/bin/webide.png
Name[zh_CN]=phpStorm           
Name=phpStorm       
Path=
StartupNotify=true
Terminal=false
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=
X-KDE-SubstituteUID=false
X-KDE-Username=Learn Programming

说明一下 Exec 是执行文件的路径,Icon 是图标的路径,Categories 是分类,这个根据系统来就可以了

然后执行下面两行代码

1
2
sudo mv Phpstorm.desktop /usr/share/applications/
sudo chmod +x Phpstorm.desktop

这样就 ok 了,在 application 目录里面就会有 phpstorm了,就这么简单,这个适用于 debain 系列,其他应用也是这样添加就ok了

话说以前看过很多算法相关的书,大部分讲的都很模糊,然后直接上代码,当时看似理解了,可是时间一长就忘光光了,以前看书学习的都是如何去做,而自己也没有深入的思考过为何这么做,单纯的就是背下来那种。当学习到一定程度之后,发现基础知识还是非常重要的。

今天要说的就是分治法,什么是分治法,就是分而治之,先把把大的问题分解为小一些的问题。逐步把小问题解决了,在把这些解决的小问题合并了就把大问题解决了,这就是我所理解的分治法。

我们在看算法排序相关的时候,都会有并归排序和快速排序,这两个方法都是用分治法解决的,只不过解决的方案不一样。下面是我用 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
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
/**
* 归并排序
* @param $arr
* @return array
*/
function mergeSort($arr)
{
$arrCount = count($arr);
if ($arrCount < 2) {
return $arr;
}
$mid = ceil($arrCount / 2); // 向上取整一下
$leftArr = array_slice($arr, 0, $mid);
$rightArr = array_slice($arr, $mid, $arrCount - $mid);
return mergeArr(mergeSort($leftArr), mergeSort($rightArr));
}

/**
* 最终合并数组的方法
* @param $leftArr
* @param $rightArr
* @return array
*/
function mergeArr($leftArr, $rightArr)
{
$i = 0;
$j = 0;
$returnArr = [];
while ($i < count($leftArr) && $j < count($rightArr)) {
if ($leftArr[$i] < $rightArr[$j]) {
$returnArr[] = $leftArr[$i];
$i++;
} else if ($leftArr[$i] > $rightArr[$j]) {
$returnArr[] = $rightArr[$j];
$j++;
} else {
$returnArr[] = $leftArr[$i];
$returnArr[] = $rightArr[$j];
$i++;
$j++;
}
}
for ($temp = $i; $temp < count($leftArr); $temp++) {
$returnArr[] = $leftArr[$temp];
}
for ($temp = $j; $temp < count($rightArr); $temp++) {
$returnArr[] = $rightArr[$temp];
}
return $returnArr;
}

/**
* 快速排序
* @param $arr
* @return array
*/
function quickSort($arr)
{
if (count($arr) < 2) {
return $arr;
}
$flag = $arr[0];
$lessArr = [];
$largeArr = [];
$flagArr = [];
$flagArr[] = $flag;

for ($i = 1; $i < count($arr); $i++) {
if ($arr[$i] < $flag) {
$lessArr[] = $arr[$i];
} else if ($arr[$i] > $flag) {
$largeArr[] = $arr[$i];
} else {
$flagArr[] = $arr[$i];
}
}

return array_merge(quickSort($lessArr), $flagArr, quickSort($largeArr));
}

先来说一下快排,因为快排的代码比较简短。快排的解决方案是,找出一个数字,一般都是采用数组的第一个数字作为标识数字,然后把比这个数字小的放到一个数组里面,在把比这个数字大的放到一个数组里面。这样,我们就已经确定好中间的数字了,然后我们在采用递归的方式分别处理比标志位数字小的数组和比标志位大的数组。 但是在处理递归的时候我们要注意一个点,就是何时终止递归,让其返回,这个点就是当数组的元素个数小于2的时候,因为这个时候已经不需要进行比较了。

好吧,简单吧,其实我们可以用笔在纸上画一画模拟一下流程,就会更加的清晰。

再来说说归并,归并理解起来要比快排麻烦一些,因为并没有那么直观,不直观的原因就是最后一步了,我们从头开始吧。归并排序思想就是把数组折半拆分,然后拆成一个个的小单元,那么多小是小呢,就是上面快排说的终止点,这个终止点就是当数组元素小于2的时候,因为这个时候已经没有办法继续拆分了。拆分后就是合并,那么如何合并呢,这个合并就是我个人认为复杂地方,合并的是偶我们比较每个数组的值,具体的方法看看代码吧,就是利用游标。找出小的来,然后放到结果数组中,这样一次次的合并之后每个小数组就都是有序的,然后在一次次的合并回去,这个归并我觉得看看就好了,实际上就用快排好啦。起码我个人没用过归并在实际项目中。

好吧上面简单的说了一下两个排序的方式,其实我最想说的就是分治法,其实在我刚开始学习算法的时候就是知道了哦,这个排序是利用分治法,那么如何分而治之我却没有深入的了解,在最近看一个老外的算法书的时候忽然灵光一闪,想把这两个方式比较一下,也就有了今天的文章。其实啊,现在再让我说什么事分治法,我也会说把大问题分解成小问题,小问题解决后,合并到大问题上面也就解决了。说了半天还是废话把,再想想上面两个排序拆分的方式,差别就是拆分方式不同,这其实才是我想说的,观看问题的角度不同,解决方案也不同,多看看别人的代码,多思考自己的方案,多学习。才能更灵活,我个人觉得学习算法不是让我们死记硬背应付面试的,而是拓宽了我们的思路,在合适的时候选用合适的方法罢了。

加油吧,新的算法书看了44%了,这周争取搞定,虽然之后200页。

图片alt

话说许久没有写技术类的笔记了,也该写点东西了,距离上次说 container 已经过去4个月了,期间也一直在学习,但是不知道写点什么好,说实话还是很怀念 14 年下半年,那半年的进步真的很大,那时候自己愿意看东西,也愿意写东西,也许写东西能让自己进步更快吧,所以17年了也应该继续进步了,否则问题大大的啊,下班的时候跟小伙伴聊天,做技术的就应该一直学习,否则就会被拉下很远很远。好了,说了这么多废话,说点正文吧,其实,想写 laravel 的 container 的笔记的,可是,自己看了许久,也没有很好的理解,理解到的部分也是很片面的东西,不过 laravel 的 container 真的很强大,要比今天写的这个强大的多,不过强大的带来的问题,就是可能会慢,毕竟用到了反射,今天这个 Pimple 则相对简单的多了,没有那么多复杂的东西,用起来也很顺手而且比较容易理解,所以今天就用这个做笔记了。

原本想分段做这个的笔记的,后来觉得应该吧知识点拆分开说明,然后再用整体代码在里面做注释的方式来解释这段更好一些,于是乎,准备开整,btw,过几天准备更新一下编辑器,现在这个自己搞得编辑器还是有些简陋的。好吧,进入正文了。

1
class Container implements \ArrayAccess

这个类实现了 ArrayAccess 接口,ArrayAccess 是个什么东西了,大家首先看一下 PHP 官网的手册 http://php.net/manual/zh/class.arrayaccess.php 好吧,我就简单说一句,就是让对象能够像数组一样操作了。具体需要实现的几个接口,大家看一下手册吧,我觉得我的说明肯定没有手册写得好,我更多理解的东西,会在代码注释中写一下。

1
2
3
4
5
6
7
8
9
public function __construct(array $values = array())
{
$this->factories = new \SplObjectStorage();
$this->protected = new \SplObjectStorage();

foreach ($values as $key => $value) {
$this->offsetSet($key, $value);
}
}

在构造方法中又出现了 SplObjectStorage 类,那么这个 SplObjectStorage 是个什么东西呢,我们再去看一下手册 http://php.net/manual/zh/class.splobjectstorage.php 这个在手册中可惜翻译的不完全(根本没有翻译),所以我就简单的说说,这个类其实是实现了 Countable , Iterator , Serializable , ArrayAccess 这4个接口,这4个接口大家也可以看一下手册,看完了就知道这个类是干什么的了,我再来拆分说下 Countable 就是让一个类可以用一个计数器, Iterator 就是可以用 foreach 这些去循环,Serializable 就是可以序列化,ArrayAccess 上面说过了就不多说了。其实刚开始很难理解这个类,不过多看看手册,别人的示例代码,自己在多写一些可能就了解了。这个如何理解我也说不太好。大家见谅。

好吧,我觉得是额外知识点的就上面那些,等多的笔记我将在下面的代码注释中说明白,大家可以看看,顺便帮忙指正。

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
<?php

/*
* This file is part of Pimple.
*
* Copyright (c) 2009 Fabien Potencier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

namespace Pimple;

/**
* Container main class.
*
* @author Fabien Potencier
*/
class Container implements \ArrayAccess
{
private $values = array(); // 存储 value 的数组
private $factories; // 存储工厂方法的对象
private $protected; // 存储保护方法的对象
private $frozen = array(); // 存储冻结的数组,也就是在这个数组里面的 key 的 value 是不可更改的了
private $raw = array(); // 存储
private $keys = array(); // 存储 key 的数组

/**
* Instantiate the container.
*
* Objects and parameters can be passed as argument to the constructor.
*
* @param array $values The parameters or objects.
*/
public function __construct(array $values = array())
{
// 构造工厂对象以及保护方法对象
$this->factories = new \SplObjectStorage();
$this->protected = new \SplObjectStorage();
// 把初始化的值存放到现有的里面
foreach ($values as $key => $value) {
$this->offsetSet($key, $value);
}
}

/**
* Sets a parameter or an object.
*
* Objects must be defined as Closures.
*
* Allowing any PHP callable leads to difficult to debug problems
* as function names (strings) are callable (creating a function with
* the same name as an existing parameter would break your container).
*
* @param string $id The unique identifier for the parameter or object
* @param mixed $value The value of the parameter or a closure to define an object
*
* @throws \RuntimeException Prevent override of a frozen service
* 设置相关值以及对象
*/
public function offsetSet($id, $value)
{
// 如果这个值被 frozen 了,就不允许更改了
// 应该是为了保持高效性,会把 get 过的值存储起来,所以就不在调用了也就不允许更改了
// 其实也可以更改,在下面的方法中说明
if (isset($this->frozen[$id])) {
throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id));
}
// 存储值方法
$this->values[$id] = $value;
// 存储 key 的值
$this->keys[$id] = true;
}

/**
* Gets a parameter or an object.
*
* @param string $id The unique identifier for the parameter or object
*
* @return mixed The value of the parameter or an object
*
* @throws \InvalidArgumentException if the identifier is not defined
* 获取值得方法
*/
public function offsetGet($id)
{
// 如果没有设置 key 则抛出异常
if (!isset($this->keys[$id])) {
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
}

// 如果 raw 里面已经有了, 或者 values 里面存储对应 key 的值不是个 obj,或者 protected 里面也有对应的值 或者值里面的方法存在,则直接返回,values 数组里面的结果
if (
isset($this->raw[$id])
|| !is_object($this->values[$id])
|| isset($this->protected[$this->values[$id]])
|| !method_exists($this->values[$id], '__invoke')
) {
return $this->values[$id];
}

// 如果工厂方法里面设置了相关方法则要直接返回
if (isset($this->factories[$this->values[$id]])) {
return $this->values[$id]($this);
}

// 获取值里面的方法
$raw = $this->values[$id];
// 执行上面获取到的方法获取返回值 并且覆盖 values
$val = $this->values[$id] = $raw($this);
// 把原始方法存储到 raw 数组里面,用来给 raw 方法调用
$this->raw[$id] = $raw;
// 把这个值设置为冻结,不允许将来的更改
$this->frozen[$id] = true;
// 返回结果值
return $val;
}

/**
* Checks if a parameter or an object is set.
*
* @param string $id The unique identifier for the parameter or object
*
* @return bool
* 获取 key 是否存在
*/
public function offsetExists($id)
{
return isset($this->keys[$id]);
}

/**
* Unsets a parameter or an object.
*
* @param string $id The unique identifier for the parameter or object
* 删除掉 key
*/
public function offsetUnset($id)
{
// 如果存在则删除相关的值
if (isset($this->keys[$id])) {
// 如果存储的是个对象,则删除相关的值
if (is_object($this->values[$id])) {
unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]);
}
// 删除普通数组里面的值
unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]);
}
}

/**
* Marks a callable as being a factory service.
*
* @param callable $callable A service definition to be used as a factory
*
* @return callable The passed callable
*
* @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
* 设置工厂方法
*/
public function factory($callable)
{
if (!method_exists($callable, '__invoke')) {
throw new \InvalidArgumentException('Service definition is not a Closure or invokable object.');
}

$this->factories->attach($callable);

return $callable;
}

/**
* Protects a callable from being interpreted as a service.
*
* This is useful when you want to store a callable as a parameter.
*
* @param callable $callable A callable to protect from being evaluated
*
* @return callable The passed callable
*
* @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
*/
public function protect($callable)
{
if (!method_exists($callable, '__invoke')) {
throw new \InvalidArgumentException('Callable is not a Closure or invokable object.');
}

$this->protected->attach($callable);

return $callable;
}

/**
* Gets a parameter or the closure defining an object.
*
* @param string $id The unique identifier for the parameter or object
*
* @return mixed The value of the parameter or the closure defining an object
*
* @throws \InvalidArgumentException if the identifier is not defined
* 其实这个就是获取设置的对象或者方法
*/
public function raw($id)
{
if (!isset($this->keys[$id])) {
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
}
if (isset($this->raw[$id])) {
return $this->raw[$id];
}

return $this->values[$id];
}

/**
* Extends an object definition.
*
* Useful when you want to extend an existing object definition,
* without necessarily loading that object.
*
* @param string $id The unique identifier for the object
* @param callable $callable A service definition to extend the original
*
* @return callable The wrapped callable
*
* @throws \InvalidArgumentException if the identifier is not defined or not a service definition
* 修改已经存在的值
*/
public function extend($id, $callable)
{
if (!isset($this->keys[$id])) {
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
}

if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {
throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));
}

if (!is_object($callable) || !method_exists($callable, '__invoke')) {
throw new \InvalidArgumentException('Extension service definition is not a Closure or invokable object.');
}

$factory = $this->values[$id];

$extended = function ($c) use ($callable, $factory) {
return $callable($factory($c), $c);
};

if (isset($this->factories[$factory])) {
$this->factories->detach($factory);
$this->factories->attach($extended);
}

return $this[$id] = $extended;
}

/**
* Returns all defined value names.
*
* @return array An array of value names
* 获取所有的 key
*/
public function keys()
{
return array_keys($this->values);
}

/**
* Registers a service provider.
*
* @param ServiceProviderInterface $provider A ServiceProviderInterface instance
* @param array $values An array of values that customizes the provider
*
* @return static
* 注册自己的服务用的,后续文章体现
*/
public function register(ServiceProviderInterface $provider, array $values = array())
{
$provider->register($this);

foreach ($values as $key => $value) {
$this[$key] = $value;
}

return $this;
}
}

好吧,上面注释的都已经写出来了,个人觉得很简单,但是有几个方法我觉得可以扩展开来说,可能在过几天的文章里面展开来说说,基本上就是 register、extend和 raw 这几个方法的具体说明了。

哦对了,开始我觉得 factory 和 protect 方法差不多,其实还是有区别的,就是 factory 会有一个 $container 的参数,protect 方法就是存储的普通方法,区别就这么简单了。不过更多的方法,也会在后续文章说明的。

先说点没用的,工作了3年了,相关东西也都接触一些,但是前端呢,还是按照以前的套路,做页面模版,写 js,写 css,但是现代相关的东西却没有深入的了解过。这不好啊,趁着现在有些空闲时间就想学习一下vue,但是 vue-cli 是使用 webpack 打包的,所以第一步就应该学习一下 webpack 趁机了解一下现代前端的开发思想。

本篇笔记总结自: http://www.jianshu.com/p/42e11515c10f,并针对笔记当日的最新版本对配置项进行响应的配置

####安装 webpack

1
2
3
4
//全局安装
npm install -g webpack
//安装到你的项目目录
npm install --save-dev webpack

####编译项目

1
webpack {entry file/入口文件} {destination for bundled file/存放bundle.js的地方}

####不适用繁杂的命令,使用配置文件编译项目

1
2
3
4
5
6
7
module.exports = {
entry: __dirname + "/app/main.js",//已多次提及的唯一入口文件
output: {
path: __dirname + "/public",//打包后的文件存放的地方
filename: "bundle.js"//打包后输出文件的文件名
}
}

####使用 node 的 package.json 设置 script 来执行编译

1
2
3
// 在package.json 的 scripts 里面添加下面的命令
"build": "webpack"
// 前面的是指在利用 npm run 后面执行的命令,问号后面的是真正执行的命令

####使用webpack构建本地服务器

1
2
3
4
5
6
7
// 在 webpck.config.js 加入下面的配置文件
devServer: {
contentBase: "./public",//本地服务器所加载的页面所在的目录
// colors: true,//终端中输出结果为彩色 新版本貌似不需要这个了
historyApiFallback: true,//不跳转
inline: true//实时刷新
}

大概就这么多吧,Loader 和 Bable 没有总结,毕竟这两个扩展性比较强,需要用的时候,在查或者看文档就 ok 了,基本上 webpack 也就了解了一下了。

嘿呀,好久没有写东西了,很爽啊,正在逐步找回节奏,慢慢笔记会更好的。加油

本来这篇文章想写一个不利用轮子在laravel上实现rbac的东西的,其实也就是自己造一个rbac的轮子。

但是,最后自己还是懒了,不想写代码,所以呢,聊聊从权限管理让我思考的分解系统的一些东西吧,其实也不算是分解系统,仅仅就是想说说松耦合的事情。

曾经我以为我自己了解的不够多,但是通过这半年换工作以后我才意识到我了解的很多了,只不过有很多东西仅仅就是了解的程度而已,没有实践经验并没有什么卵用,而且了解的越多,不知道的就越多,就包括这次的权限控制这些东西,以前我总是认为这是个很高大上的东西,后面的学习我知道了rbac就是角色权限这些东西,现在我又认识到,这些东西应该是可以热插拔的可替换的,不应该对现有系统造成任何影响,也就是说我撤除掉权限相关的东西系统应该可以正常运行下去,还有,其实造一个轮子很难啊,因为可能需要我们为不同的框架去做相应的适配。

学习,永远都停不下来,我也不知道我上面说的东西对不对。就这样吧,看东西去了

对了,最重要的东西没说,说说思路。

首先我们应该有一个baseModel,所有的model对象都继承自baseModel,baseModel里面有hasRole,hasPermission,can ,cannot等这些方法用于权限的验证,然后blade那边我们也应该有相应的控制,至于角色权限相关,就按照自己的思路定义就可以了。

一些都应该是可替换的

图片alt

又用了一次老图片,这个图片我个人真的炒鸡喜欢呢。

说正事吧,10天前,我开始着手写自己的php框架,目前仅仅把路由和mvc中的vc实现了出来,说实话写框架真的不是那么简单的事情,需要考虑的东西要比平时写逻辑多得多。也可能是我考虑的太多,就是那些有的没的很容易中断我的思路,而且总想用上最新的东西,让自己的框架看起来高达上一些,所以最先想实现出来的就是这个container了。框架也许会中断一阵,然后从小的组建弄起,先准备弄一个pdo的封装,然后这个pdo的封装就成为我框架重的m了。

好吧,又跑偏了,继续说container,以前弄java的时候ssh框架就多次提到了ico啊di啊什么的,也许是当时自己的知识不够吧,仅仅是那么用而已,具体为什么却没有去考究,做开发3年多了,现在我也算是理解了。下面就说说我们为什么需要一个container作为全局容器呢。就是为了ioc/di。

那么ioc/di是什么呢,这两个其实是一个意思,就是什么控制反转,依赖注入,这两个词描述的是一个事情,只不过是从不同的方向说的而已。以前我们在开发的时候需要一个什么东西,构造好,传递进去,为什么不说在类里面初始化呢,这也是解耦嘛。现在为什么要依赖注入呢,早年的php框架各自为政没有太多的需求,现在psr标准出来了,composer有了很多的组件让我们来使用,标准就越来越凸显了,大家的选择就有很多,我们在各种标准接口上实现自己的类,就可以无缝替换了。也许有朋友会说。上面的方式也ok啊,改个代码就行了,但是不得不说的是这是极度危险的,当有一处忘记改动了,就会有很大的问题。所以,有一个容器统一管理我们的各种组件就是很重要的了。然后我们修改config中的相关项就可以了,这样就会很安全。

好吧,上面就是我的理解,没有一个代码,真的不愿意贴代码啊。

btw,美好的周六这么过去了,没写代码,现在写点吧,开始弄pdo

1
2
3
<div style="height:50px;position: absolute; top: 0px;right: 0px; overflow: hidden;">
<div style="font-size: 12px;text-align: center;position: relative; top: -5px;right: -52px; z-index: 999; background: #ff0000;color: #f3f3f3;transform:rotate(45deg);padding: 12px 50px 3px 50px;">Beta</div>
</div>

单纯是公司用到了,需要记录下,具体参数可以自行调整,外部 div 就是为了防止溢出用的了

PHP正则表达式实现@某人
if(preg_match_all(‘#@\w+#u’, ‘@张全蛋 含泪质检@三星Note7 被炸飞,听说@炸机 跟@啤酒 更配哦!’, $matches)) {
var_export($matches);
}
//输出
array (
0 =>
array (
0 => ‘@张全蛋’,
1 => ‘@三星Note7’,
2 => ‘@炸机’,
3 => ‘@啤酒’,
),
)
正则表达式 #@\w+#u 中:
#是分隔符.
u是修饰符,表示Unicode.
\w是元字符,在ASCII下等价于[A-Za-z0-9_],在Unicode下表示字符(包括汉字)和数字和下划线.
+是量词,表示1个或多个,等价于{1,}

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
<?php

function sortArr($arr) {
if (count($arr) < 2) {
return $arr;
}
$mid = count($arr) / 2;
$arr1 = array_slice($arr, 0, $mid);
$arr2 = array_slice($arr, $mid, count($arr));
$arr1 = sortArr($arr1);
$arr2 = sortArr($arr2);

return mergeArr($arr1, $arr2);
}

function mergeArr($arr1, $arr2) {

if (!is_array($arr1)) {
$arr1[] = $arr1;
}
if (!is_array($arr2)) {
$arr2[] = $arr2;
}

$i =0;
$j = 0;
$arr1Length = count($arr1);
$arr2Length = count($arr2);
$returnArr = [];
while($i < $arr1Length && $j < $arr2Length) {
if($arr1[$i] > $arr2[$j]) {
$returnArr[] = $arr2[$j];
$j++;
} else {
$returnArr[] = $arr1[$i];
$i++;
}
}
for($tmp = $i; $tmp < $arr1Length; $tmp++) {
$returnArr[] = $arr1[$tmp];
}
for($tmp = $j; $tmp < $arr2Length; $tmp++) {
$returnArr[] = $arr2[$tmp];
}
return $returnArr;
}

$arr = [1,3,2,5,7,9,3,1];


$sortableArr = sortArr($arr);

foreach ($sortableArr as $a) {
print_r($a . "\n");
}

说实话,算法这东西,挺好玩的,以前还搞过快排,但是忘却了,今天这个归并排序应该很难忘记了,毕竟理解起来要比快排好得多,但是快排回来后面补充