php网站开发零基础教程学习(php手把手教你做网站)
我所说的可能很多人都知道,掌握得也比较片面,只是平时的一些积累,希望能给初学者一些帮助吧。
如果有没有考虑到的,欢迎留下您的想法,让我们一起把网站做得更好、更安全。
1、在public下边新建文件夹,名称自己随意设定(这里假设名称web)。
- 都知道网站内有固定的public文件夹,如果只是放到public里边和放到根目录也没啥区别;
- 文件夹的名称不要有什么规律(单词之类的),我们越好记,别人就越容易猜到;
- 将tp程序文件放到web文件夹内,不是说tp的系统程序不安全,而是用的人多发现漏洞的可能就大,藏起来,安全性会得到一些提高;
- 前台程序也放到web文件夹下的时候,直接访问网站是不能访问的,因为根目录下没有首页文件,所以在根目录下新建入口文件:index.php;
- 如果只是新建index.php作为首页文件,而不是作为入口,url重写规则要做一下改变;
- 如果是程序员做多个网站,最好每个网站web文件夹名称都不相同,可以随机几个字母;
图1 tp5 程序都放到了public文件夹内
图2 tp6程序到了public内
如图,感觉整洁了不少
1)根目录下入口文件index.php
tp5入口文件
<?php
define('APP_PATH',__DIR__.'/public/web/application/');
define('ROOT_PATH',realpath(__DIR__)."/");
// 加载框架引导文件
require __DIR__ . '/public/web/thinkphp/start.php';
?>
说明:
APP_PATH,和require的路径都加上了/public/web
tp6入口文件
namespace think;
require __DIR__ . '/public/web/vendor/autoload.php';
// 执行HTTP应用并响应
$http = (new App())->http;
$response = $http->name('index')->run();
$response->send();
$http->end($response);
2)入口文件对应iis重写规则
<rule name="main" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^(.*)$" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/public/web/index.php/{R:1}" />
</rule>
说明:
- <match url="^(.*)$" ignoreCase="false" />我以前直接用好像有的public下的css被重写了,现在用的又没问题,忘记以前是什么情况下出现的了,如果直接用有错误,可以尝试换成<match url="^((?!public).*)$" ignoreCase="false" />;
- <conditions logicalGrouping="MatchAll">内的设计,我个人理解就是文件存在不重写;
3)根目录下index.php只是作为网站的首页访问
这个时候文件内容是什么,没有任何区别,可以是空白,反正填写任何内容都不会显示出来。
4)根目录下index.php 对应url重写规则
<rule name="main" stopProcessing="true">
<match url="^((?!public).*)$" ignoreCase="false" />
<action type="Rewrite" url="/public/web/index.php/{R:1}" />
</rule>
说明:
作用是排除掉public文件夹全部重写,public/web/文件夹下要有入口文件。
5)网站根目录下有的时候生成sitemap.xml
如果这个时候使用的是第4步的重写规则,直接访问http://www.abc.com:8080/sitemap.xml,是被重写的,需要我们在规则内排除一下sitemap
<rule name="main" stopProcessing="true">
<match url="^((?!(public|sitemap)).*)$" ignoreCase="false" />
<action type="Rewrite" url="/public/web/index.php/{R:1}" />
</rule>
2、文件夹关闭目录浏览
- 通常默认的可能就是禁止目录浏览的,可以自己测试一下 网址/你的文件夹名称,如果能看到该文件夹下的文件或者子文件夹说明没有禁止目录浏览;
- 如果不能操控服务器禁止目录浏览,可以在该文件夹下加一个首页文件(index.php或者index.html等等,根据你的默认首页文件名),该文件可以是空白内容;
3、图片上传
如果使用的是tp自带的上传,可能这些都有判断,我是用的以前的,安全性靠自己去提高。
1)图片改了扩展名上传
上传以后进行判断,getimagesize("E:\phpweb\about.jpg");可以返回图片的宽度,高度,mime类型,图片的mime类型有image/gif,image/jpeg,image/png其他的,比如:bmp图片,几乎用不到可以不考虑。通过判断类型是否这3个里边的,得出结论是否是图片,如果不是,unlink()删除该图片;
$pic="E:\phpweb\about.jpg";
$picinfo=getimagesize($pic);
$mimearr=array('image/gif','image/jpeg','image/png');
$mime=$picinfo['mime']??'';
if(!in_array($mime,$mimearr)){
@unlink($pic);
echo JSON_encode(array('error'=>'0001','msg'=>"可疑文件,禁止上传"),JSON_UNESCAPED_UNICODE);
exit;
}
2)图片文件包含了木马
- 上传之前可以判断,通过获取tmp_name判断图片内是否有危险字符(来源网络);
- 在php.ini配置了upload_tmp_dir存放临时上传的文件,上传完成以后会移动到我们设定的目录;
- tmp_name就是这个临时文件名称;
if (file_exists($tmp_name)) {
$resource = fopen($tmp_name, 'rb');
fseek($resource, "0");
$fileSize = filesize($tmp_name);
if ($fileSize > 512) { // 若文件大于521B文件取头和尾
$hexCode = bin2hex(fread($resource, "512"));
fseek($resource,$fileSize-512);
$hexCode .= bin2hex(fread($resource, 512));
}else{ // 取全部
$hexCode = bin2hex(fread($resource, $fileSize));
}
if (preg_match("/(3c25.*?28.*?29.*?253e)|(3c3f.*?28.*?29.*?3f3e)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)/is", $hexCode)){
$status = 5;
}else{
$status = 0;
}
}
说明:
$status安全码,返回0正常,5包含了可疑代码;
4、富文本编辑器默认所在文件夹
有的编辑器,集成了很多功能,直接处理上传,上传的图片,也会在编辑器的文件夹内,
- 我们需要更改编辑器默认的文件夹名称,可以是任意的最好不要有什么规律,防止有漏洞被人直接网址访问进行危险操作;
- 如果上传的图片是在编辑器所在文件夹,要进行修改,不能让别人通过查看文章内的图片路径得到编辑器所在文件夹;
5、管理员登陆密码错误次数限制
- 在后台登陆入口暴露以后,防止有人暴力破解,可以限制该账号错误次数,例如:错误3次,该账号锁定,当天不能再次登陆;
- 验证码感觉作用不是很大,很多软件都可以自动识别验证码;
6、登陆错误提示
- 不要账号错误提示账号错误,密码错误就提示密码错误,这样会导致破解的人知道是账号或者密码错了;
- 错误提示应该是:账号或者密码;
- 平时测试的时候,我们会常用admin或者admin888之类的账号,密码也都是一样的,在网站正式上线以后,一定要记得改掉这些常用的账号、密码;
我们习惯的账号密码,别人猜起来就会容易。
7、过滤危险字符防止sql注入
URL参数、文章搜索、留言板,我使用的是360提供的防sql注入类(Webscan)。
IndexController.php
class IndexController extends CmController {
}
CmController.php
use checkdanger\Webscan;
class CmController extends BaseController {
public function __construct(){
header("Content-Type:text/html; charset=utf-8");
$webscan = new Webscan();
if ($webscan->check()) {
echo '系统检测到有攻击行为存在!';
exit;
}
}
说明:
所有的页面先继承了CmController.php,CmController.php继承BaseController,构造函数内进行判断包含危险性字符,登陆过期等等。
8、不要显示详细错误信息
- tp5的调试模式:在application文件夹config.php,app_debug改为false,错误提示页面在thinkphp/tpl/think_exception.tpl;
- tp6调试模式:在.env文件APP_DEBUG改为false;config文件夹下app.php文件拉到最下边,show_error_msg改为false;错误提示页面vendor\topthink\framework\src\tpl/think_exception.tpl;
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com