首页
技术笔记
网址导航
Json在线解析
二维码
Ip地址查询
在线流程图
新用户注册
|
会员登录
在线工具
开发笔记
毒鸡汤
网址导航
免费在线流程图
11赞
362
当前位置:
开发笔记
>
编程语言
> 正文
40个迹象表明你还是PHP菜鸟
作者:coco2冰冰 | 2021-08-02 00:01
40个迹象表明你还是PHP菜鸟,阅读40个迹象表明你还是PHP菜鸟,这些迹象不只是用来告诉我是菜鸟,还告诉我还有很多要学习的。简介40个迹象的英文版权归ReinholdWeber所有,中译文作者yangyang(akadavidkoree)。双语版可用于非商业传播,但须注明英文版作者、
这些迹象不只是用来告诉我是菜鸟,还告诉我还有很多要学习的。
简介
40个迹象的英文版权归Reinhold Weber所有,中译文作者yangyang(aka davidkoree)。双语版可用于非商业传播,但须注明英文版作者、版权信息,以及中译文作者。翻译水平有限,请广大PHPer指正。
40个Conquer的作者是《PHPer》李俊鹏,可用于非商业传播。
正文
我愿意把本文归入我的“编程糗事”系列。尽管在正规大学课程中,接触到软件工程、企业级软件架构和数据库设计,但我还是时不时地体会到下述事实带给我的“罪恶”感,当然,都是我的主观感受,并且面向Eclipse。
你是PHP菜鸟,如果你:
1. 不会利用如phpDoc这样的工具来恰当地注释你的代码
Conquer 1
phpDoc是PEAR下的一个优秀模块,如同javadoc一样为代码生成API文档。phpDoc采用OOP的思想编写,它扫描指定目录下的PHP源码,识别出注释中的专用标记然后生成XML文件(或其它),然后建立相应的索引。即本质是从源码中的注释生成文档。
2. 对优秀的集成开发环境如Zend Studio或Eclipse PDT视而不见
Conquer 2
我不知道该怎么描述Zend,只是夜色里有人曾这么说过:PHP界的Zend如同软件界的微软;而Eclipse则是另一款多功能的开发环境,想来大多数人都是用它来写Java的(比如我),而PDT即PHP Development Tools则是可以使用户可以在Eclipse写PHP的插件。BTW,如果有兴趣,你也可以自己为Eclipse开发个插件。^_^
3. 从未用过任何形式的版本控制系统,如Subclipse
Conquer 3
版本控制系统?还是先了解一下版本控制吧:版本控制就是数据仓库,它可以记录你对文件的每次更改。这样自然也就了解了什么是版本控制系统了。而进一步的了解不是三两句可以结束的,所以直接推荐,自己选择一个吧!
(1)
http://www.phpchina.com/bbs/thread-46209-1-1.html
(2)
http://bbs.phpchina.com/thread-47473-1-1.html
(3)
http://bbs.phpchina.com/thread-89264-1-1.html
4. 不采用某种编码与命名标准,以及通用约定,不能在项目开发周期里贯彻落实
Conquer 4
我觉得良好的代码书写习惯令人很舒服,缩进实在是必需的——要不看着那一堆密密麻麻毫无美感的代码,实在令人郁闷。缩进一般是4个空格,PEAR标准中不建议使用TAB键(在这里我小小汗颜一下),因为有些场合会出现问题(虽然我还没遇到)。而命名建议变量:第一个单词小写开头,其它大写开头如:myName,而类名建议都大写开头如:MyName或者My_Name,至于用不用下划线我觉得差别不大(如果很大请指教)。
5. 不使用统一开发方式
Conquer 5
由于还是个人PHP爱好者,所以对于团队共同开发还是经验匮乏的,在此,对于开发方式这个词有种好像理解又不理解的错觉,而且利用搜索引擎好久也很难找到一篇比较满意的文章,所以直接推荐:
(1)
http://www.phpchina.com/html/42/1142-7314.html
(2)
http://topic.csdn.net/u/20080509/09/9b81d740-68fc-4d63-9299-ce6675f240cb.html
(3)
http://www.ibm.com/developerworks/cn/web/wa-jacquard/index.html#N10064
其实,个人觉得开发方式这个词挺泛、挺抽象……
6. 不转换(或)也不验证某些输入或SQL查询串(译注:参考PHP相关函数)
Conquer 6
始终坚信一点:绝不相信未经处理的用户输入。而过滤用户输入是Web安全的基础。所以设计者始终应该清楚地知道数据的来源、过滤数据、将已经处理过的数据和未处理的数据区分开。
7. 不在编码之前彻底规划你的程序
Conquer 7
我个人觉得这点和写程序前画流程图之类或者做项目的开发流程一样,应该不需要过多解释。
8. 不使用测试驱动开发
Conquer 8
测试驱动开发(Test Driven Development,英文缩写TDD)是极限编程的一个重要组成部分,它的基本思想就是在开发功能代码之前,先编写测试代码。也就是说在明确要开发某个功能后,首先思考如何对这个功能进行测试,并完成测试代码的编写,然后编写相关的代码满足这些测试用例。然后循环进行添加其他功能,直到完成全部功能的开发。代码整洁可用(clean code that works)是测试驱动开发所追求的目标。(摘自百度百科)
9. 不在错误开启状态下进行编码和测试(译注:参考PHP函数error_reporting)
Conquer 9
我想一般写代码的时候都会开启错误报告吧。这里顺便了解下error_reporting原型为int error_reporting([ int $level]),该函数的作用是设置要显示报告的错误等级,详情参阅:
http://cn2.php.net/manual/en/function.error-reporting.php
10. 对调试器的好处视而不见
Conquer 10
推荐几款调试器:
(1)Zend IDE
(2)APD
(3)Xdebug
11. 不重构你的代码
Conquer 11
重构是指使用一系列重构准则(手法),在不改变“软件之可察行为”前提下,调整其结构,是对软件内部结构的一种调整。目的是在不改变“软件之可察行为”前提下,提高其可理解性,降低其修改成本。重构的好处能改进软件设计使软件更容易被理解,帮助设计者找到BUG,并且提高软件的开发速度。简而言之,重构就是改进已经写好的软件的设计。
12. 不使用类似MVC模式把程序的不同层次划分开
Conquer 12
MVC(Model View Controller)即模型—视图—控制器,视图是呈现给用户的一面,模型则是处理任务的模块,而控制器则是控制视图和模型间的映射,即在用户响应下选择何种模型进行处理,而任务处理后控制以何种视图呈现。
13. 不知道这些概念:KISS、DRY、MVC、OOP、REST
Conquer 13
(1)KISS是指Keep It Simple,Stupid(摘自wikipedia),指设计时要坚持简约原则,避免不必要的复杂化。
(2)DRY是指Don't Repeat Yourself(摘自wikipedia),特指在程序设计以及计算中避免重复代码,因为这样会降低灵活性、简洁性,并且可能导致代码之间的矛盾。
(3)OOP即Object-Oriented Programming,是指面向对象的程序设计。我一直觉得经典的比喻是汽车是一个类(Class),而这个类的属性有轮子、车身、马达等,方法有加速、减速等;而劳斯莱斯就是一个对象(Object)了,这个对象继承了汽车这个类的属性和方法;而如何实现加速、减速?这样的信息被隐藏了——即信息封装(封装),只留下用户接口给我们了,比如踩刹车、踩油门;至于多态嘛,我粗糙比喻下就是一台自动贩卖机(我们假设它每种价格只有一款饮料),同样是投币这种方法,但是你投进去2元跟5元得到的结果是不一样的——当然,除非这贩卖机有问题。
(4)REST(Representational State Transfer)是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。REST提出了一些设计概念和准则:
a. 网络上的所有事物都被抽象为资源(resource);
b. 每个资源对应一个唯一的资源标识(resource identifier);
c. 通过通用的连接器接口(generic connector interface)对资源进行操作;
d. 对资源的各种操作不会改变资源标识;
e. 所有的操作都是无状态(stateless)。(摘自百度百科)
14. 不用return而是直接在你的函数或类中输出(echo/print)内容
Conquer 14
这一点,观摩大虾的源代码都是用return的,所以我一般也这么学习使用这,至于原因,我就是觉得这样用感觉蛮好的。或许是严禁风格吧。但是其实我对这句有点不理解,函数一般都是需要返回语句的嘛,除非是专门用来输出的函数。
15. 对单元测试或通用测试的优点视而不见
Conquer 15
(1)单元测试是在软件开发过程中要进行的最低级别的测试活动,在单元测试活动中,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试,不仅能保证项目进度还能优化设计。我记得我以前在写比较长的C代码的时候都会在特定模块结束时补一段测试代码来检验,不知道算不算。^_^
(2)通用测试技术?这让我想起图书馆里图灵系列图书的一本《软件测试****》,具体名字忘记了。这些都是属于软件测试的范畴,如果需要可以下载:
http://bbs.phpchina.com/thread-94241-1-1.html
16. 总是返回硬编码的HTML,却不返回纯粹的数据、字符串或对象
17. 总是对“消息”和“配置参数”进行硬编码
Conquer 16-17
硬编码的使用会造成程序的不灵活,以后修改的复杂问题,还有可能会遇到编译的问题。更具体了解:
http://bbs.bc-cn.net/thread-32143-1-6.html
18. 不对SQL查询语句做优化
Conquer 18
SQL语句的优化是将性能低下的SQL语句转换成目的相同的性能优异的SQL语句。这样的好处是显而易见的,可使用人工智能自动SQL优化。
19. 不使用__autoload(译注:参考PHP手册相关描述)
Conquer 19
__autoload函数会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP出错失败前有了最后一个机会加载所需的类。详见:
http://cn.php.net/__autoload
20. 不允许智能错误处理(译注:参考PEAR的ErrorStack)
Conquer 20
PEAR_ErrorStack提供了一种基于堆栈的错误处理方法,将各种错误统一起来指向同一个地方以达到把多个无关项目连接到同一个应用程序的目的。(译自:
http://pear.php.net/package/PEAR_ErrorStack
)
21. 使用$_GET替代$_POST来做具有破坏性的传递操作
Conquer 21
个人理解,使用$_GET会使一些信息暴露在URL中。
22. 不知道怎么利用正则表达式
Conquer 22
正则表达式?我想可以去夜色找找shanji,或者到夜色共享手册里下载一本学习:
http://bbs.phpchina.com/thread-89223-1-1.html
23. 从未听说过SQL注入或跨站脚本
Conquer 23
(1)所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过Web表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击;
(2)业界对跨站攻击的定义如下:“跨站攻击是指入侵者在远程Web页面的HTML代码中插入具有恶意目的的数据,用户认为该页面是可信赖的,但是当浏览器下载该页面,嵌入其中的脚本将被解释执行。”由于HTML语言允许使用脚本进行简单交互,入侵者便通过技术手段在某个页面里插入一个恶意HTML代码,例如记录论坛保存的用户信息(Cookie),由于Cookie保存了完整的用户名和密码资料,用户就会遭受安全损失。如这句简单的Java脚本就能轻易获取用户信息:alert(document.cookie),它会弹出一个包含用户信息的消息框。入侵者运用脚本就能把用户信息发送到他们自己的记录页面中,稍做分析便获取了用户的敏感信息。(摘自百度百科)
24. 不允许简易配置,也不允许类的构造函数接受参数传递而后执行set/get方法,或运行时的常量定义
Conquer 24
就一句话:不要不允许类的构造函数接受参数传递。
25. 不理解面向对象编程(OOP)的优势和劣势
26. 不视情形大小而滥用OOP
27. 自认为实现可复用的软件一定等于/需要让你的代码遵循OOP
Conquer 25-27.
OOP的优点:使人们的编程与实际的世界更加接近,所有的对象被赋予属性和方法,结果编程就更加富有人性化。OOP的缺点:就C++而言,由于面向更高的逻辑抽象层,使得C++在实现的时候,不得不做出性能上面的牺牲,有时候甚至是致命的。
28. 不利用智能缺省值
Conquer 28
我想,使用缺省值是个好习惯。
29. 没有单一的配置文件
Conquer 29
专门设置个config.php我想是需要的。
30. 不想暴露文件源码,却用.inc后缀名取代了.php
Conquer 30
*.inc文件顾名思义是include file的意思,一般我们使用inc作为后缀,是因为这样能体现该文件的作用。*.inc文件的作用有点类似于C/C++内的*.H、*.HPP头文件,使用inc文件可以使我们的程序,增加可读性,更易于开发和维护。
31. 不使用数据库抽象层
Conquer 31
请参考
http://bbs.phpchina.com/thread-94258-1-1.html
32. 不能保持DRY作风,即不重复自己,如果你总是在复制粘贴一些东西,说明你设计得很差劲
Conquer 32
请参考13点
33. 没有实现让一个函数/类/方法只做一件事,也不能组合利用它们
Conquer 33
这需要锻炼,在实践中学习、完善着。
34. 没能尝试OOP的特长,如抽象类、接口、多态、继承,访问控制修饰符(译注:如public、private、protected)
Conquer 34
哦,my god,我想还是参考25-27吧,也是需要在实践中成长的。
35. 不用现有的设计模式优化你的程序体系设计
Conquer 35
推荐《Head First》设计模式
36. 不允许你的用户在你拥有很多文件或目录的情况下定义基础目录
Conquer 36
保留,这点我有点懵。^_^
37. 污染了名称空间,比如用常见字符串命名你的库函数
Conquer 37
哎,这实在是个不好的习惯,不过好习惯是养成的!
38. 使用数据库表时不使用表前缀
Conquer 38
我想,可能,PHPChina的数据表的前缀是PPC_或者PCC_。这的确是有好处的,我觉得,就好像字段名使用如txtUsername这样的格式。
39. 不使用统一的模板引擎
Conquer 39
这我都有点不知道该怎么说了,一个团队一般都使用统一的模板引擎吧。
40. 不关注已有的PHP开发框架,懒于探索;其实先进的开发理念和美妙代码就蕴含其中。
Conquer 40
比如Zend Framework、CakePHP、FleaPHP、ThinkPHP等。
推荐阅读
程序员
使用张量板时,如何总结在几个小型计算机上计算的损失?
如何解决《使用张量板时,如何总结在几个小型计算机上计算的损失?》经验,为你挑选了1个好方法。 ...
[详细]
程序员
如何在非播放应用程序中使用play框架配置库命令行参数
如何解决《如何在非播放应用程序中使用play框架配置库命令行参数》经验,为你挑选了1个好方法。 ...
[详细]
程序员
如何检测导航抽屉外的触摸事件
如何解决《如何检测导航抽屉外的触摸事件》经验,为你挑选了1个好方法。 ...
[详细]
程序员
TypeError:需要类似字节的对象,而不是python和CSV中的'str'
如何解决《TypeError:需要类似字节的对象,而不是python和CSV中的'str'》经验,为你挑选了2个好方法。 ...
[详细]
程序员
使用UUIDField作为主键时,如何判断模型实例是否是新的
如何解决《使用UUIDField作为主键时,如何判断模型实例是否是新的》经验,为你挑选了0个好方法。 ...
[详细]
程序员
dnx-clr-win-x86.1.0,0,rc1-final和dnx-clr-win-x86.1.0,0.rc1-update1之间的区别
如何解决《dnx-clr-win-x86.1.0,0,rc1-final和dnx-clr-win-x86.1.0,0.rc1-update1之间的区别》经验,为你挑选了2个好方法。 ...
[详细]
程序员
关闭未知长度的通道
如何解决《关闭未知长度的通道》经验,为你挑选了1个好方法。 ...
[详细]
程序员
如何使用SQLAlchemy定义没有主键的表?
如何解决《如何使用SQLAlchemy定义没有主键的表?》经验,为你挑选了1个好方法。 ...
[详细]
程序员
如何在工具栏下方放置溢出菜单而不是溢出菜单以重叠工具栏
如何解决《如何在工具栏下方放置溢出菜单而不是溢出菜单以重叠工具栏》经验,为你挑选了1个好方法。 ...
[详细]
程序员
为什么pandas将unsigned int大于2**63-1转换为对象?
如何解决《为什么pandas将unsignedint大于2**63-1转换为对象?》经验,为你挑选了1个好方法。 ...
[详细]
程序员
如何在C++中隐藏我的AWS S3访问密钥和密钥?
如何解决《如何在C++中隐藏我的AWSS3访问密钥和密钥?》经验,为你挑选了0个好方法。 ...
[详细]
程序员
alvarotrigo.com/fullPage/和bootstrap 3网格问题
如何解决《alvarotrigo.com/fullPage/和bootstrap3网格问题》经验,为你挑选了0个好方法。 ...
[详细]
程序员
格式化图表中的数字ios swift
如何解决《格式化图表中的数字iosswift》经验,为你挑选了1个好方法。 ...
[详细]
程序员
允许Google Compute Engine(GCE)中的WebSockets
如何解决《允许GoogleComputeEngine(GCE)中的WebSockets》经验,为你挑选了1个好方法。 ...
[详细]
程序员
构建GoogleSignInOptions时的firebase serverClientId
如何解决《构建GoogleSignInOptions时的firebaseserverClientId》经验,为你挑选了2个好方法。 ...
[详细]
程序员
如何使用Realm排序?
如何解决《如何使用Realm排序?》经验,为你挑选了1个好方法。 ...
[详细]
程序员
toLocaleLowerCase()和toLowerCase()之间的区别
如何解决《toLocaleLowerCase()和toLowerCase()之间的区别》经验,为你挑选了1个好方法。 ...
[详细]
程序员
For循环在Groovy和Java中的工作方式不同
如何解决《For循环在Groovy和Java中的工作方式不同》经验,为你挑选了1个好方法。 ...
[详细]
程序员
如何在Android中从名称或lat获取PlaceID?
如何解决《如何在Android中从名称或lat获取PlaceID?》经验,为你挑选了1个好方法。 ...
[详细]
程序员
在原生Android文件选择器中按mimetype或extention进行过滤
如何解决《在原生Android文件选择器中按mimetype或extention进行过滤》经验,为你挑选了0个好方法。 ...
[详细]
吐了个 "CAO" !
吐个槽吧,看都看了
会员登录
|
用户注册
coco2冰冰
这个屌丝很懒,什么也没留下!
关注作者
Tags | 热门标签
actionscrip
bash
c#
c++
c语言
erlang
flutter
go
golang
java
javascript
lua
node.js
perl
php
python
scala
typescript
RankList | 热门文章
1
在TMemo中锁定文本的开头
2
如何以这种格式验证字符串:p [1或更多数字]?
3
如果a的值是5,那么a ++ + a的值是多少?
4
如何将命令行参数转换为双数组以计算总和?
5
iOS有类似Android的RecyclerView吗?
6
在Haskell中生成下一个词典字符串
7
使用rustc_serialize并获取不带引号的字符串
8
skimage调整大小给出奇怪的输出
9
在更新面板内自动将文件上载到服务器第一次不起作用
10
C++体系结构x86_64的未定义符号
11
有没有办法在Haskell中模拟线性类型?
12
按条件跨多个列交换值
13
如何在matplotlib中更改科学记数法的字体大小?
14
解决错误“与返回的局部变量关联的堆栈内存地址”
15
Windows命令:如何使用chdir推送当前目录以便以后弹出?
16
ObjectResult <T>不可用的异步方法
17
如何在java中获取Path的长度?
18
在cx_Oracle中使用with cursor on cursor
19
关于返回STL容器数据成员而不调用复制构造函数
20
brew install opencv3显然是成功的,但缺少cv2.so和cv2.py
DevBox开发工具箱 | 专业的在线开发工具网站
京公网安备 11010802040832号
|
京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有