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

0%

最新需要写一些 js 的东西,正好就想试用一下 typescript 试用以后感觉舒服,那么需求来了,我们需要编译出来的文件,在外部可以调用,所以就有了下面的笔记

参考文章https://www.cnblogs.com/mahidol/p/8874300.html

npm 安装依赖

1
npm install --save-dev typescript ts-loader webpack webpack-cli

在项目根目录创建两个文件夹 srcdist 以及一个测试用的入口文件 index.html

src 用来存放我们的源码
dist 用来保存生成后的源码

index.html 的内容

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

</body>
<script type="text/javascript" src="./dist/app.js" ></script>
</html>

入口文件仅仅是用来测试的,所以仅仅引入了输出的js 我们在 chrome 控制台测试

根目录创建 typescript 配置文件 tsconfig.json

1
2
3
4
5
6
7
8
9
10
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true
},
"exclude": [
"node_modules"
]
}

创建 webpack 配置文件,采用https://www.webpackjs.com/guides/production/
中的方案,只不过有些小修改

安装 webpack-merge

1
npm install --save-dev webpack-merge

webpack.common.js 公用的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const path = require('path');

module.exports = {


entry: './src/index.ts',
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist')
},

module: {
rules: [{
test: /\.ts$/,
use: "ts-loader"
}]
},
resolve: {
extensions: [
'.ts'
]
}
};

webpack.dev.js 开发中的配置文件

1
2
3
4
5
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
});

webpack.prod.js 输出的的配置文件

1
2
3
4
5
6
7
8
9
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
output: {
filename: 'app.min.js',
path: path.resolve(__dirname, 'dist')
},
});

package.json 中增加两条命令

1
2
"start": "webpack --config webpack.dev.js",
"build": "webpack --config webpack.prod.js"

这里跟文档不一样,毕竟文档的开发部分配置文件用的测试服务器,我们这个单纯的就是自己测试,所以依然还是用 webpack 命令编译一下。

至此,我们在普通场景下已经可以使用了。但是由于我们的需求是,这个文件不仅仅在 html 中调用,还需要在外部调用编译出来的代码,但是上面的代码是在外面无法调用的,所以我们继续搞。

webpack.common 配置文件中的 output 属性增加两个配置

1
2
library: "MediaParser",
libraryTarget: 'var',

简单点说就是导出为名称为 MediaParser 的变量,这样我们就可以在外部 scrpit 中调用了

具体的这两个参数可以看 webpack 中的文档https://www.webpackjs.com/configuration/output/#output-librarytarget https://www.webpackjs.com/guides/author-libraries/

收工

最近在学习 laravel psssport ,可是在本地使用 docker 测试的时候却遇到了一个报错。

1
cURL error 7: Failed to connect to movielaravel.test port 80: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

想了很久,一开始以为是内循环了,但是使用 postman 却可以得到正确的结果,后来想到,是不是因为 docker 容器内部无法解析到 我的测试域名呢,搜索了一波,在 docker-compose 文件中配置了 extra_hosts 问题的到解决,难受,活生生被阻挡了2个小时。

在需要内部调用的地方,增加配置,示例如下

1
2
extra_hosts:
- "movielaravel.test:172.28.12.3"

这样,就在docker的内部,做好host的映射了,也就能够正常访问了

laravel 的命令,以前就是简单的用了,并没有很仔细的用。

今天在写一个 artisan 命令的时候就踩了很多坑,其实可能就是自己以前并没有注意过,所以这次要记录下来。

1
2
3
4
5
6
7
8
9
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'user:create
{password : the user password}
{--username=admin : the user username}
{--email=admin@email.com : the user email}';

冒号后面可以写说明文字,在用 –help 的时候可以看到

在 输出 table 的时候 还得注意穿进去的 row 得是个二维数组

图片alt

原文地址:http://php-di.org/doc/understanding-di.html

题外话,原本是想直接翻译这篇文章的,但是后来想想还是算了,采用翻译 + 自己理解的方案来写东西,这样自己也很舒服

依赖注入和依赖注入容器的区别

  • 依赖注入是帮助你编写更好的代码的一种方法
  • 容器是帮助依赖注入的工具

个人理解,依赖注入其实就是一种编程的模式,是代码耦合性更低,方便我们替换某些代码部件, 而容器则是实现这个依赖注入模式的工具

####对比 传统编写代码的方式 和 依赖注入的 区别

#####传统编写方式

  • 应用需要 Foo 类:
  • 应用创建 Foo:
  • 应用调用 Foo:
    • Foo 依赖 Bar
    • Foo 创建 Bar
    • Foo 调用 Bar
      • Bar 依赖 Bim
      • Bar 创建 Bim
      • Bar 做一些事情

#####使用依赖注入方式

  • 应用需要 Foo, Foo 需要 Bar, Bar 需要Bim:
  • 应用创建 Bim
  • 应用创建 Bar 并且把 Bim 传递给 Bar
  • 应用创建 Foo 并且把 Bar 传递给 Foo
  • 应用调用 Foo
    • Foo 调用 Bar
      • Bar 做一些事情

上面说的是一种叫做 控制反转 的模式。就是是调用者和被调用者的依赖反过来。

这样做的好处是,我们可以自主的控制依赖的关系,并且容易替换

说了这么多,不如上代码来的实在

图片alt

图片alt

乍一看这种方式,写代码反而会更多一些,毕竟以前我们只需要 new 一个 Foo 就可以了,现在反而多写了几行,但是请让我们思考一下,为什么这么做,好了,我继续说吧,我个人理解这么做的原因是,方便我们做一些替换,是我们能够减少代码的修改,比如以前 Bar 我们就当做一个发送邮件的服务,以前我们不想发送邮件了,想改用发送短信的方式,那么我们就得修改Foo的代码了,那么采用依赖注入有什么好处,我们在外面实例化Bar的时候就实例为短信服务就好了,Foo完全不用修改了,也减少我们修改多个代码的风险。这里又得多说几句了,一般在构造的时候参数大都是一个接口,然后各个服务实现接口的方法,完成各自的功能。

最后说一下使用容器的方法

  • 应用需要 Foo
  • 应用从容器中获取 Foo
    • 容器创建 Bim
    • 容器创建 Bar 并且把 Bim 传递给 Bar
    • 容器创建 Foo 并且把 Bar 传递给Foo
  • 应用调用 Foo
    • Foo 调用 Bar
      • Bar 做一些事情

其实使用容器的一个好处就是方便我们管理所有的依赖项,毕竟集中管理要比分散在代码各处要靠谱的多,但是上面说的容器,其实还有个自动分析依赖的功能,但是有一些容器并不具备这个功能,比如以前我们分析过的 Pimple 。 pimple这个东西真的就是一个容器,我们把需要的东西放置进去就好了。至于依赖什么的自己提前编排好,就ok了。不自动分析的好处是快,坏处嘛就是可能得多写一些代码。

好,今天就到这,感觉有些东西没有说清楚,不要急,不要急。以后还有

图片alt

这一周纠结了一些其他的问题,所以依然停留在了第五集。不过有一些关于测试的想法,还是要梳理一下的。

以前我总是纠结测试,比如说测试一个模型返回的字段是否齐全什么的,后来想想其实我们可以一个一个的assert。

然后还有一个问题是,比如我们没有返回某些字段,那么我们在模型里面定义的一些衍生字段是否还有效,这个让我明天测试一下。

然后依然继续学习如何做测试,就说到这吧,得去调整一下dns有些慢

图片alt

今天学习了第三集和第四集,下面依然是个人总结

  1. 没错,第三集用到了单元测试也就是 unit 的部分,跟我之前看其他文章了了解的差不多, feature 主要用来测试面向用户的功能 unit 是用来测试我们内部功能的,也就是一个个的最小单元,或者其他的合并单元,然后由这些单元组合成为 controller 里面的代码最终呈现给用户,然后 feature 再来测试 controller 里面的代码。
  2. 关于测试以前都是弄出一个数据然后我们自己调试页面然后观察数据,现在就可以用 unitfeature 来让机器帮我们判定了。我们期待什么值,就让他来断言一下就ok了,但是个人还是比较担心出问题,比如数据不全神马的,这个还得后期继续考虑一下
  3. factorymakecreate 的区别, make 仅仅是生成了数据,create 不仅仅是生成了数据,并且将数据保存到数据库中,所以 create 可以理解为首先 make 然后 save 了。
  4. 在测试文件中 be 方法的作用,就是把当前我们生成的用户,设置为登录状态
  5. 在测试的时候不仅要测试正常的情况,也要测试异常的情况
  6. 功能职责要分清楚,比如发布 Reply 的时候就应该把方法写入到 ReplyController
  7. 关联关系居然可以添加数据,详情参见这里吧 https://laravel.com/docs/5.6/eloquent-relationships#the-create-method

图片alt

今天学习了第二节,原以为一节课只有不到10分钟,一天可以学习好几节,但是呢,自己就得去学习不足的知识,结果不到一个10分钟的课程,自己就扩展到了将近40分钟,好了,说说今天的心得

  1. 在写功能之前,先做好测试用例,这样可以方便我们去实现功能,也可以提供思路
  2. 在 laravel 的 test 文件夹中有两个字文件夹,分别是 featureunit 这两个一个是功能测试一个是单元测试,就在这里我去查了一下东西,但是理解的也不是很好下面说说自己的理解
    • 功能测试是面向用户的,也就是说我们需要测试代码中的 controller 部分,为什么这么说呢,因为只有 controller 部分才是面向用户的,不论这个功能有多大,这里面一个方法都是对用户的。
    • 单元测试就可以理解为其他的部分了,因为 controller 里面的代码都是由剩余部分的代码组成的,所以这些都是一个个的子单元
    • 其他部分的代码也有可能由其他的部分一起组成,所以我个人觉得也应该写单元测试
    • 不知道上面说的对不对
  3. 写代码的时候应该划分好各自的职责

图片alt

这个教程是 laracasts 上面的一个系列教程,对于我来说有很多比较多的东西没有接触过,所以起码看完第一集来说对我还是很有帮助的,在其他论坛也是有相关笔记的,我仔细想了一下如果也是想他们那样记录每一步的操作来说意义并不大,毕竟我可以直接看他们的文章。所以这里面还记录一些我个人的感悟

  1. 初步了解了 factory 的用法,比如在 thinker 虚拟数据,在测试的时候模拟数据,但是更多的东西还得看看文档才可以
  2. 以后再使用 php artisan 命令的时候多多看看 --help 会有很多简便的方式让我们能少执行几个命令 比如 php artisan make:model xxxModel -mr 这个命令就会帮助我们生成 resource 形式的 controller 以及迁移文件。
  3. 在 laravel 5.6 中 factory 是分文件的,个人理解可能会比较清晰,不用全部都写在一个文件里面了。方便管理

最后,再说一句,弄这个东西,给我的docker完善了不少

话说在住院的时候,想起来了以前看过的一个帖子有说在加载 psr4 的时候记录的 namespace 的长度是用来替换路径用的。

但是在今天中午去看加载源码的时候发现已经没有这个替换了。于是赶紧翻看 github 上面的改动记录,发现已经不使用那种方式了,而是采用截取的方式去获取文件名什么的。然后路径就直接使用现存的了。

代码如下图

图片alt

估计等在过一段那个 namespace 的长度也可以不用了,但是看改动记录,还是存在,静待观察

今天在公司写东西的时候遇到了一个奇怪的小问题,就是在用 curl 模拟文件上传的时候发现上传失败,最初始采用的代码如下

1
2
3
[
'file' => '@' . $fileName
]

通过查看文档发现了下面的一段说明

图片alt

从这可以得知,CURLOPT_SAFE_UPLOAD 这个参数可以控制,由于 php 5.5 以前的默认值是 false ,所以我可能以前并没有关注,但是在 php 5.6 的时候这个默认值是 true 了,所以当我们想要采用上面那种方式就需要设置 CURLOPT_SAFE_UPLOAD 这个值为 false 才可以使用。

但是需要注意的是在 php 7 以后这个属性被删除了,所以当我们想要上传的时候,必须采用 CURLFile 才可以上传。具体可以参见 http://php.net/manual/zh/class.curlfile.php

所以现在就不要考虑 CURLOPT_SAFE_UPLOAD 这个参数了,以后在模拟上传的时候直接采用 CURLFile 就可以了