分类 PHP 下的文章

今天无语中查了下阿里云虚拟主机的访问历史, 发现之前使用WordPress被莫名其妙的写入一堆英文的文章的原因查到了, 登录接口被暴力破解导致的, 所有时间比较急, 就写了个简单的POST请求的安全控制的代码, 使用也很简单, 直接在程序入口直接require 这个文件即可, 需要保证这个配置文件定义的限流锁文件保存路径具有写权限

可以看出, 一个登录请求了那么多次, 没办法, 紧急写了个比较粗糙的代码

<?php

// 简单的全局请求安全限制接口
class RequestLimit
{

    protected $configFilePath = 'request_limit.lock';
    protected $config = [
        'GET' => [],// 定义需要限流的类型, 如果不想写配置, 那么就默认以default配置为准
    ];
    protected $default = [
        'rate' => '10/60|20/600|30/3600|100/43200|200/86400', // 限制10次/60s, 20次/10分钟, 30次一小时
        'try_cont' => 0,
        'save_history_count' => 100, // 保留历史条数
        'try_history' => [],
    ];

    public function __construct()
    {
        if (file_exists($this->configFilePath)) {
            $this->config = json_decode(file_get_contents($this->configFilePath), true);
        }
    }

    public function handle($method)
    {
        if (!array_key_exists($method, $this->config)) {
            return;
        }
        if (empty($this->config[$method])) {
            $this->config[$method] = $this->default;
        }
        $this->config[$method]['try_history'] = empty($this->config[$method]['try_history']) ? [] : $this->config[$method]['try_history'];
        // 再次请求频率判断, 通过才让继续
        foreach (explode('|', $this->config[$method]['rate']) as $item) {
            [$x, $y] = explode('/', $item);
            if (!empty($this->config[$method]['try_history'][$x - 1]) && $this->config[$method]['try_history'][$x - 1] + $y >= time()) {
                header('HTTP/1.1 429 Too Many Requests');
                echo '429 Too Many Requests';
                exit;
            }
        }
        if (empty($this->config[$method]['save_history_count'])) {
            $this->config[$method]['save_history_count'] = 100;
        }
        array_unshift($this->config[$method]['try_history'], time());
        $this->config[$method]['try_history'] = array_slice($this->config[$method]['try_history'], 0, $this->config[$method]['save_history_count']);
        $this->config[$method]['try_cont'] = empty($this->config[$method]['try_cont']) ? 1 : $this->config[$method]['try_cont'] + 1;
        $this->saveConfig();
    }

    public function saveConfig()
    {
        file_put_contents($this->configFilePath, json_encode($this->config, 256));
    }
}

$q = new RequestLimit();
$q->handle($_SERVER['REQUEST_METHOD']);

执行composer install, composer update, php artisan tinker, php artisan cache:clear 等等等 . . .
都抛出下面的错误

  • 通过各种排查, 文件为下面这个路径的该文件
\vendor\laravel\framework\src\Illuminate\Container\Container.php
  • 最后问题还是解决了
在laravel的composer引入的公共文件中, 发现了使用request类的发放, 导致命令行无法正常的执行下去

<?php
function tree($directory)
{
    $mydir = dir($directory);
    echo "<ul>";
    while ($file = $mydir->read()) {
        if ($file == "." || $file == "..") {
            continue;
        }
        if (is_dir("$directory/$file")) {
            echo "<li><font color='blue'><b>$file/</b></font></li>";
            tree("$directory/$file");
        } else {
            echo "<li>$file</li>";
        }
    }
    echo "</ul>";
    $mydir->close();
}

echo "<h2>目录为蓝色</h2>";
tree(".");

压缩文件夹

因为打算使用php打包目录, 网上搜了搜现成的代码, 基本无用, 才写一下

<?php

function files($directory, &$fileList = [])
{
    $mydir = dir($directory);
    while ($file = $mydir->read()) {
        if ($file == "." || $file == "..") {
            continue;
        }
        if (is_dir("$directory/$file")) {
            files("$directory/$file", $fileList);
        } else {
            $fileList[] = $mydir->path . "/" . $file;
        }
    }
    $mydir->close();
    return $fileList;
}

function packageZip($dir, $savePath = null)
{
    if (!is_dir($dir)) {
        echo '<font style="color: red;">' . $dir . '不是一个目录</font>';
        return;
    }
    $savePath = empty($savePath) ? $dir . date("Y-m-d") . '.zip' : $savePath;
    $zip = new ZipArchive;
    is_file($savePath) ? unlink($savePath) : '';
    $res = $zip->open($savePath, ZipArchive::CREATE);
    if ($res === TRUE) {
        foreach (files($dir) as $item) {
            $zip->addFile($item);
        }
        $zip->close();
    }
}

packageZip('wuloves');

<?php
php header() 常用content-type
//定义编码
header( 'Content-Type:text/html;charset=utf-8 ');

//Atom
header('Content-type: application/atom+xml');

//CSS
header('Content-type: text/css');

//Javascript
header('Content-type: text/javascript');

//JPEG Image
header('Content-type: image/jpeg');

//JSON
header('Content-type: application/json');

//PDF
header('Content-type: application/pdf');

//RSS
header('Content-Type: application/rss+xml; charset=ISO-8859-1');

//Text (Plain)
header('Content-type: text/plain');

//XML
header('Content-type: text/xml');

// ok
header('HTTP/1.1 200 OK');

//设置一个404头:
header('HTTP/1.1 404 Not Found');

// 请求频繁 429:
header('HTTP/1.1 429 Too Many Requests');

//设置地址被永久的重定向
header('HTTP/1.1 301 Moved Permanently');

//转到一个新地址
header('Location: http://www.example.org/');

//文件延迟转向:
header('Refresh: 10; url=http://www.example.org/');
print 'You will be redirected in 10 seconds';

//当然,也可以使用html语法实现
// <meta http-equiv="refresh" content="10;http://www.example.org/ />

// override X-Powered-By: PHP:
header('X-Powered-By: PHP/4.4.0');
header('X-Powered-By: Brain/0.6b');

//文档语言
header('Content-language: en');

//告诉浏览器最后一次修改时间
$time = time() - 60; // or filemtime($fn), etc
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT');

//告诉浏览器文档内容没有发生改变
header('HTTP/1.1 304 Not Modified');

//设置内容长度
header('Content-Length: 1234');

//设置为一个下载类型
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="example.zip"');
header('Content-Transfer-Encoding: binary');
// load the file to send:
readfile('example.zip');

// 对当前文档禁用缓存
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Pragma: no-cache');

//设置内容类型:
header('Content-Type: text/html; charset=iso-8859-1');
header('Content-Type: text/html; charset=utf-8');
header('Content-Type: text/plain'); //纯文本格式
header('Content-Type: image/jpeg'); //JPG***
header('Content-Type: application/zip'); // ZIP文件
header('Content-Type: application/pdf'); // PDF文件
header('Content-Type: audio/mpeg'); // 音频文件
header('Content-Type: application/x-shockw**e-flash'); //Flash动画

//显示登陆对话框
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Top Secret"');
print 'Text that will be displayed if the user hits cancel or ';
print 'enters wrong login data';

// 下载xlsx文件
$filename = rtrim($_SERVER['DOCUMENT_ROOT'],'/').'/app/files/payment_status.csv';  
header('Content-Disposition: attachment; filename=payment_status.xlsx');  
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');  
header('Content-Length: ' . filesize($filename));  
header('Content-Transfer-Encoding: binary');  
header('Cache-Control: must-revalidate');  
header('Pragma: public');  
readfile($filename);