写给刚入行的程序员

源地址: 顶级程序员

1.作为前端开发者,使用双显示器能大幅提高开发效率。

2.学编程最好的语言不是PHP,是English。

3.自己做的东西交付之前先测试一遍。

4.问别人之前最好先自己百度,google一下,以免问出太低级的问题。

5.把觉得不靠谱的需求放到最后做,很可能到时候需求就变了,或者取消了。

6.读好书,垃圾书会浪费你时间。

7.不要炫技,面向人脑编程更便于维护。

8.没事别重复造轮子,你造的轮子大多数时候只有你觉得好用。接手你的轮子的人会在背后骂你上百遍。

9.不要先写框架再写实现。最好反过来,从原型中提炼框架。

10.新技术一定不要找书,书一旦印出来就过时了。

11.请勿久坐,多喝水,尤其是遇到很久都解决不了的问题的时候,多走动走动。

12.考虑可维护性比考虑性能更重要。

13.越难解决的bug往往犯的错误越低级。

14.比起鼓励师,不如给程序员找一个靠谱的产品经理。

15.熬夜低效率写代码,不如好好睡觉。

16.你遇到的问题,大多数人都遇到过,并且网上都有完整的解决方案,你找不到,只是你懒得去找。

17.多沟通,不少加班工作是由于沟通少造成的。

18.普通程序员+google=超级程序员。实在不行,百度也可以,学会利用搜索引擎来辅助自己解决问题。

19.早点找女朋友,生活作息会更健康。你懂的!

20.永远别小看程序媛。即使是青铜,说不定背后有个王者在帮她。

PHP开发清单

最近读了<<清单革命>>后, 感觉清单很适合程序员使用, 可以避免一些低级错误, 有效降低线上bug发生的概率.

本地开发清单

  • 需求分析
  • 数据库字段设计
  • 构建代码框架
  • 上线差异化配置说明
  • 具体逻辑实现
  • 本地新功能测试
  • 测试关键模块是否正常
  • 边界值测试
  • 注入测试
  • 查看 sql 日志
  • 查看 错误 日志
  • 提交代码

上线清单

  • 列出新版本更新功能
  • 确认所有开发人员代码是否提交
  • 更新本地代码
  • 清除本地所有日志
  • 测试本地所有新功能是否正常
  • 测试关键模块是否正常
  • 边界值测试
  • 注入测试
  • 查看 sql 日志
  • 查看 错误 日志
  • 上线部署

php高效率计算文件行数

  1. /*
  2. * 高效率计算文件行数
  3. */
  4. function count_line($file)
  5. {
  6. $fp = fopen($file, "r");
  7. $i = 0;
  8. while (!feof($fp)) {
  9. // 每次读取2M
  10. if ($data = fread($fp, 1024 * 1024 * 2)) {
  11. // 计算读取到的行数
  12. $num = substr_count($data, "\n");
  13. $i += $num;
  14. }
  15. }
  16. fclose($fp);
  17. return $i +1;
  18. }
  19. $count = count_line($filename);
  20. echo $count;

vagrant+docker一键搭建php+mysql开发环境

必备软件

  1. Vagrant
  2. Virtual Box

启动脚本

  1. Vagrantfile
  1. Vagrant.configure("2") do |config|
  2. config.vm.box = "ubuntu/xenial64"
  3. config.vm.network "forwarded_port", guest: 80, host: 80
  4. config.vm.network "forwarded_port", guest: 3306, host: 3306
  5. config.vm.network "private_network", ip: "10.0.0.2"
  6. config.vm.provision "shell", inline: <<-SHELL
  7. # 更换aliyun软件源
  8. cp /etc/apt/sources.list /etc/apt/sources.list.bak
  9. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse' > /etc/apt/sources.list
  10. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse' >> /etc/apt/sources.list
  11. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse' >> /etc/apt/sources.list
  12. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse' >> /etc/apt/sources.list
  13. echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> /etc/apt/sources.list
  14. apt-get update
  15. # 安装docker
  16. apt-get -y install apt-transport-https ca-certificates curl software-properties-common
  17. curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
  18. add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
  19. apt-get -y update
  20. apt-get -y install docker-ce docker-compose
  21. # 使用aliyun加速docker镜像
  22. mkdir -p /etc/docker
  23. echo '{' > /etc/docker/daemon.json
  24. echo ' "registry-mirrors": ["https://kag9wqej.mirror.aliyuncs.com"]' >> /etc/docker/daemon.json
  25. echo '}' >> /etc/docker/daemon.json
  26. systemctl daemon-reload
  27. systemctl restart docker
  28. usermod -G docker vagrant
  29. cd /vagrant
  30. docker-compose up -d
  31. # 开机自启动
  32. echo '#!/bin/bash' > /etc/rc.local
  33. echo 'sleep 10' >> /etc/rc.local
  34. echo 'cd /vagrant' >> /etc/rc.local
  35. echo 'docker-compose up -d' >> /etc/rc.local
  36. echo 'exit 0' >> /etc/rc.local
  37. sudo rm /bin/sh
  38. sudo ln -s /bin/bash /bin/sh
  39. SHELL
  40. end
  1. docker-compose.yml
  1. version: '2'
  2. services:
  3. mysql:
  4. image: mysql
  5. environment:
  6. - MYSQL_ROOT_PASSWORD=root
  7. volumes:
  8. - "./mysql:/var/lib/mysql"
  9. ports:
  10. - '3306:3306'
  11. networks:
  12. - bridge
  13. www:
  14. build: .
  15. volumes:
  16. - "./wwwroot/www:/app"
  17. - "./wwwroot/static/Uploads:/app/Uploads"
  18. environment:
  19. - VIRTUAL_HOST="你要绑定的域名"
  20. - PHP_DB_HOST=mysql
  21. - PHP_DB_NAME=你的数据库名称
  22. - PHP_DB_USER=root
  23. - PHP_DB_PASSWORD=root
  24. networks:
  25. - bridge
  26. lb:
  27. image: 'dockercloud/haproxy'
  28. volumes:
  29. - /var/run/docker.sock:/var/run/docker.sock
  30. links:
  31. - www
  32. ports:
  33. - '80:80'
  34. networks:
  35. - bridge
  36. networks:
  37. bridge:
  1. Dockerfile
  1. FROM php:5.6-apache
  2. # 安装扩展
  3. COPY ./soft/*.tgz /soft/
  4. WORKDIR /soft
  5. RUN pecl install redis-3.1.6.tgz \
  6. && pecl install xdebug-2.5.5.tgz \
  7. && docker-php-ext-enable redis xdebug \
  8. && docker-php-ext-install pdo_mysql \
  9. && docker-php-ext-install mysqli \
  10. && rm -rf /soft
  11. # URL重写
  12. RUN a2enmod rewrite
  13. # 安装composer
  14. ADD ./soft/composer.phar /usr/local/bin/composer
  15. RUN chmod 755 /usr/local/bin/composer \
  16. && composer config -g repo.packagist composer https://packagist.phpcomposer.com
  17. # 安装代码
  18. COPY ./wwwroot /app/
  19. # 修改网站主目录
  20. ENV APACHE_DOCUMENT_ROOT /app
  21. RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
  22. RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
  23. # 可写权限
  24. RUN chmod -R 777 /app/
  25. # 默认工作目录
  26. WORKDIR /app
  27. # 暴露工作端口
  28. EXPOSE 80 443 22

基于 Composer 的 PHP 模块化开发

转载, 文章原始地址: https://zhuanlan.zhihu.com/p/27943241
订阅号:假装我会写代码

这个话题之前是在微博公司内部做的技术分享,这里拿出来分享给大家。

基于 GitHub 或者其它平台托管的开源项目的引入大家应该都已经非常熟悉了,但是公司内部项目的模块化应该怎么做呢?这或许是不少朋友头疼的问题。

我们先聊聊 PHP 模块化开发演进的过程,在没有 GitHub 之前,我们大家获取与分享代码的方式主要是博客,国内的 CSDN 或者博客园还有很多很多,大家都是从文章内复制到自己项目里面使用。现在看起来真的是相当原始粗暴,但是那个时代也没有太多可选的方案。导致的现象就是一段代码在 N 个项目里出现,可能见得最多的就是获取客户端 IP 的那几行了,在互联网上不止出现了几万遍。现在很多项目里都还是这段:

是不是很熟悉?

这种引入代码的方式有很多弊端:比如不安全,因为很多人是直接复制粘贴就用上了,根本没花时间去考证它是否真的是安全的。另外一个问题就是不同步,你今天在别人那里复制过来就用上了,后来作者发现了 bug 并修复更新了文章也不会通知你,你也不可能记得这段代码来自哪里去检查更新。

在没有 Composer 之前我们是如何引入代码的呢?除了上面说的复制粘贴以外,在 PHP 中还有 pear,不过自从用过两次我就再也不用它了,一种说不出来的感觉。

不信你可以找一些旧的项目看看,在没有 Composer 之前的项目中,你会发现大量的重复代码,以及各种花样的组织格式,各种规范的写法。这也是 Composer 诞生的原因之一。

Composer 给我们带来了诸多的好处:

  • 模块化,降低代码重用成本
  • 统一的第三方代码组织方式
  • 更科学的版本更新
    这三个是比较重要的特征了,基于 GitHub 的共享代码方式解决了传统引入方式带来了各种问题。

我们先来了解一点 Composer 基础。

Composer 的实现结构相对比较简单,http://Packagist.org 是 Composer 官方数据源,它的数据基于 GitHub 等代码托管平台,你在本地使用 Composer 命令行工具,基于 http://Packagist.org 的数据信息安装与更新依赖。
本地安装 Composer 非常简单,主要有以下几种方式:

新手同学需要注意的是,这里一定要确定 composer 安装目录在环境变量 $PATH 内才能全局使用 composer 命令。

那接下来我们聊一下如何创建一个 Composer 包。

步骤很简单,创建目录,然后在目录内使用命令 composer init 按照提示完成包的初始化。

接着就是完成你的代码编写,然后在 composer.json 文件配置你的引入方式等信息。
然后我们如何对已经写好的代码进行测试呢?

我们需要在其它任何地方建立一个测试项目(不要在刚才创建的包目录就可以),比如这里我们创建一个叫 ‘my-package-test’ 的目录,然后在目录里 composer init 完成项目初始化。接着就是声明项目依赖,我们这里要依赖的就是刚才建立好的包,由于我们的包还没有发布到 packagist,所以是无法直接 composer require 来安装的,我们需要告诉 composer 从哪里加载我们的包信息:

  1. $ composer config repositories.foo path /Users/overtrue/www/foo/bar

我们通过这个命令在 composer.json 中 repositories 区块添加了一个项目源。

然后我们添加包依赖:

  1. $ composer require foo/bar:dev-master -vvv

这样就完成了包的安装,你会发现这样的安装方式它只是创建了一个软链接到包目录,所以,你在测试的时候就可以直接在 vendor/foo/bar 下修改代码,这样就加快了你的开发速度。

更多细节这里你就自己去研究了,我们来看看 composer.json 文件:

我们最需要关心的就是图里上面的三个部分了,包名、依赖、以及自动加载,是必不可少的部分。

刚才我们提到了包的安装,安装依赖包的方式主要有以下两种:

手动方式是不太推荐的,容易写错,比如后面多一个逗号之类的,不过你可以写完以后使用以下命令来验证:

  1. $ composer validate

更新依赖就非常简单了:

虽然在上一篇文章我们已经讲了语义化版本,这里再提一次:

我们在依赖一个包的时候,很多同学对于依赖的版本一直处于蒙逼状态,那看完下一页你就恍然大悟了,首先是两个符号:”~” 与 “^”

接着是版本号的范围的各种写法:

还有包含稳定性的标识:

这里需要说一下生产环境最重要也一直是好多同学不清楚的一个东西:版本锁定,很多人在纠结,要不要把 composer.lock 上传到代码库啊。我可以给你一个特别简单的判断方法:

如果你的代码是一个项目,就上传,如果是一个工具包,给大家用的,就别上传。

在已经存在 composer.lock 的目录执行 composer install 的时候,是不会分析包依赖的,它只是按 composer.lock 中描述的下载地址直接下载,所以会快很多,而且版本号是具体的。那怕包已经发了新版,只要 composer.lock 没动过,它就会按 composer.lock 里的版本来安装。composer update 时会更新 composer.lock,所以不要乱用 composer update。

包开发好了怎么发布?开源的方式是这样的:

最后一句请酌情考虑。

另外一种发布方式是闭源,公司内部用的包,上传到 GitLab 或者其它私有的代码托管平台,有两种玩法:

  1. 最容易的玩法,在 composer.json 中添加 repositories 直接用 vcs 指定代码库地址
    这样做有一个缺点,当你的包很多的时候,你全都得在 composer.json 中加上才行。

  2. 自已架设 Packagist 类似的服务,Packagist 官方提供了两款: toran,收费,开源方案是 Satis,不过它偏手动一些,自己酌情选择即可。

私有包有一个点需要注意:授权,私有包肯定都是需要授权才能访问的,这里由于方案不太通用,大家根据自己的场景来解决就好了。

另外,有一些痛点不晓得啥时候能够解决:

好在 Laravel China 已经为了我提供了国内目前最稳定最好用的镜像源,Composer 中文镜像 / Packagist 中国全量镜像正式发布!

最后总结一下:

  在 PHP 现代开发中,Composer 已经是离不开的东西了,它的确加快了我们的开发速度节省了开发成本,如果你还在纠结用不用 Composer,那你真得反思一下了。

  本文标题是模块化开发,内容主要介绍了包的创建与测试,以及公有包与私有包的发布方案。但是无法帮你解决,如何拆分项目这类问题,这得基于你的长期经验积累,但是有一些经验可以分享一下:

  • 不要过度设计,很多自以为很 NB 我不把学到的东西用上就是不爽的同学,上来就分库分表,uuid 做主键之类,项目运营了好几年一个表还没到100万条记录,也是够厉害的。

  • 不要过早设计,真正 NB 的架构是演进而来的,不是前期设计出来的,当然不是说完全不需要设计哈,恰当的根据实际情况来就好,不要立项就把“千万”、“亿级”、“百亿” 这些单位挂在嘴边,也许到你项目倒闭那天你都没到过任何一个量级。随着项目逐渐改进即可。

  • 优先关注成本,很多同学以为是性能,No! 技术团队真正的成本是人力,所以开发效率才是优先需要关注的。上次文章在发在知乎有人就强制把我的“不要首先关注性能”解读成了“性能不重要”,也是够厉害的,语文也许跟养殖场动物学的。数学正常一点的人都会算,一台服务器多少钱?一个技术员工多少钱?服务器你花 20 万是永久资产,一个员工 20 万呢?半年工资?一年工资?

一个markdown编辑器editor.md

Editor.md






Editor.md : The open source embeddable online markdown editor (component), based on CodeMirror & jQuery & Marked.

Features

README & Examples (English)


Editor.md 是一款开源的、可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。

editormd-screenshot

主要特性

Examples

https://pandao.github.io/editor.md/examples/index.html

Download & install

Github download

Bower install :

  1. bower install editor.md

Usages

HTML:

```html


php时间区间

  1. <?php
  2. echo date("Ymd",strtotime("now")), "\n";
  3. echo date("Ymd",strtotime("-1 week Monday")), "\n";
  4. echo date("Ymd",strtotime("-1 week Sunday")), "\n";
  5. echo date("Ymd",strtotime("+0 week Monday")), "\n";
  6. echo date("Ymd",strtotime("+0 week Sunday")), "\n";
  7. echo "*********第几个月:";
  8. echo date('n');
  9. echo "*********本周周几:";
  10. echo date("w");
  11. echo "*********本月天数:";
  12. echo date("t");
  13. echo "*********";
  14. echo '<br>上周起始时间:<br>';
  15. echo date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1-7,date("Y"))),"\n";
  16. echo date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7-7,date("Y"))),"\n";
  17. echo '<br>本周起始时间:<br>';
  18. echo date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1,date("Y"))),"\n";
  19. echo date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y"))),"\n";
  20. echo '<br>上月起始时间:<br>';
  21. echo date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m")-1,1,date("Y"))),"\n";
  22. echo date("Y-m-d H:i:s",mktime(23,59,59,date("m") ,0,date("Y"))),"\n";
  23. echo '<br>本月起始时间:<br>';
  24. echo date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),1,date("Y"))),"\n";
  25. echo date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("t"),date("Y"))),"\n";
  26. $season = ceil((date('n'))/3);//当月是第几季度
  27. echo '<br>本季度起始时间:<br>';
  28. echo date('Y-m-d H:i:s', mktime(0, 0, 0,$season*3-3+1,1,date('Y'))),"\n";
  29. echo date('Y-m-d H:i:s', mktime(23,59,59,$season*3,date('t',mktime(0, 0 , 0,$season*3,1,date("Y"))),date('Y'))),"\n";
  30. $season = ceil((date('n'))/3)-1;//上季度是第几季度
  31. echo '<br>上季度起始时间:<br>';
  32. echo date('Y-m-d H:i:s', mktime(0, 0, 0,$season*3-3+1,1,date('Y'))),"\n";
  33. echo date('Y-m-d H:i:s', mktime(23,59,59,$season*3,date('t',mktime(0, 0 , 0,$season*3,1,date("Y"))),date('Y'))),"\n";
  34. ?>

php操作office文档

Apicloud的云推送api, php版

  1. class ApicloudPush
  2. {
  3. public static $api = 'https://p.apicloud.com/api/push/message';
  4. public static $appid = 'A6920463******';
  5. public static $appkey = 'C******8-B6BB-3027-2C93-6C********29';
  6. public static function post($post_data)
  7. {
  8. $appkey = sha1(self::$appid . "UZ" . self::$appkey . "UZ" . time()) . "." . time();
  9. $ch = curl_init ();
  10. curl_setopt ($ch, CURLOPT_HTTPHEADER, [
  11. 'X-APICloud-AppId:'. self::$appid,
  12. 'X-APICloud-AppKey:' . $appkey
  13. ]);
  14. curl_setopt($ch, CURLOPT_POST, count($post_data));
  15. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  16. curl_setopt($ch, CURLOPT_URL, self::$api);
  17. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
  18. ob_start ();
  19. curl_exec ($ch);
  20. $result = ob_get_contents ();
  21. ob_end_clean();
  22. curl_close ($ch);
  23. return $result;
  24. }
  25. }
  26. $title = isset($_GET['title']) ? $_GET['title'] : '测试标题';
  27. $content = isset($_GET['content']) ? $_GET['content'] : '测试内容';
  28. var_dump(ApicloudPush::post([
  29. 'title' => $title,
  30. 'content' => $content,
  31. 'type' => 2, //– 消息类型,1:消息 2:通知
  32. 'platform' => 0, //0:全部平台,1:ios, 2:android
  33. // 'groupName' => 'department', //推送组名,多个组用英文逗号隔开.默认:全部组。eg.group1,group2 .
  34. // 'userIds' => 'shuai' //推送用户id, 多个用户用英文逗号分隔,eg. user1,user2。
  35. ]));

PhpStorm中文汉化