至尊技术网 - PHP https://www.zzwws.cn/tag/PHP/ zh-CN Fri, 05 Jan 2024 19:14:00 +0800 Fri, 05 Jan 2024 19:14:00 +0800 php curl无法获得https网页内容 https://www.zzwws.cn/archives/6415/ https://www.zzwws.cn/archives/6415/ Fri, 05 Jan 2024 19:14:00 +0800 悠悠楠杉 程序员最经常使用的curl,在php下面也是经常用的到。但是,博主友情提示您:用curl获取https的网页内容的时候,也是需要用到证书的。而这么多年,估计大家从来都没有察觉过任何更新证书的动作,证明这可能是有自动renew操作的。而目前博主手头的centos系统,却存在有使用curl无法获取https内容的问题。

利用curl或者file_get_contents获取远程http的内容时,成功。但是获取https的内容时,失败。错误提示文字类似于:

SSL operation failed with code 1. OpenSSL Error messages: error:14090086: SSL routines:ssl3_get_server_certificate:certificate vertify failed

解决方法

1、保证php.ini里面的openssl扩展肯定要打开。这个操作比较基础,不做赘述。

extension=openssl.so

2、查看一下openssl证书的默认位置,检测openssl的证书位置的代码:

php -r "print_r(openssl_get_cert_locations());"

default_cert_file是默认位置。

3、下载更新证书

下载网址:https://curl.haxx.se/docs/caextract.html

选择一个最新的perm证书下载即可,下载好的证书要放置在上述默认位置或者自定义好的位置,重启php后,就应该可以解决问题了。

]]>
0 https://www.zzwws.cn/archives/6415/#comments https://www.zzwws.cn/feed/tag/PHP/
ThinkPHP6 excel表导入导出 https://www.zzwws.cn/archives/6389/ https://www.zzwws.cn/archives/6389/ Tue, 03 Jan 2023 14:12:00 +0800 悠悠楠杉 composer下载phpspreadsheet

composer require phpoffice/phpspreadsheet

PhpSpreadsheet中文简介

phpexcel由于版本陈旧性能低下官方放弃维护,转而开发PhpSpreadsheet用了最新得psr标准因而对php版本不向下兼容需要注意!

PhpSpreadsheet是一个用纯PHP编写的库,提供了一组类,使您可以读取和写入不同的电子表格文件格式

PhpSpreadsheet提供了丰富的API接口,可以设置诸多单元格以及文档属性,包括样式、图片、日期、函数等等诸多应用,总之你想要什么样的Excel表格,PhpSpreadsheet都能做到

使用PhpSpreadsheet开发的PHP要求7.1或更高版本,并且支持链式操作

PhpSpreadsheet 支持的文件格式

文件路径extend/Excel.php

<?php
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use think\exception\ValidateException;

class Excel
{
    /**
     * 导入excel表格
     * @param array $file 文件路径
     * @return array|string
     */
    protected function importExcel($file)
    {
        try {
            // 截取后缀
            $fileExtendName = substr(strrchr($file, '.'), 1);
            // 有Xls和Xlsx格式两种
            if ($fileExtendName == 'xlsx') {
                $objReader = IOFactory::createReader('Xlsx');
            } else {
                $objReader = IOFactory::createReader('Xls');
            }
            // 设置文件为只读
            $objReader->setReadDataOnly(TRUE);
            // 读取文件,tp6默认上传的文件,在runtime的相应目录下,可根据实际情况自己更改
            $objPHPExcel = $objReader->load($_SERVER['DOCUMENT_ROOT'] . $file);
            //excel中的第一张sheet
            $sheet = $objPHPExcel->getSheet(0);
            // 取得总行数
            $highestRow = $sheet->getHighestRow();
            // 取得总列数
            $highestColumn = $sheet->getHighestColumn();
            Coordinate::columnIndexFromString($highestColumn);
            $lines = $highestRow - 1;
            if ($lines <= 0) {
                return '数据不能为空';
            }
            // 直接取出excle中的数据
            $data = $objPHPExcel->getActiveSheet()->toArray();
            // 删除第一个元素(表头)
            array_shift($data);
            // 返回结果
            return $data;
        } catch (ValidateException $e) {
            return $e->getMessage();
        }
    }

    /**
     * 导出excel表格
     * @param array $header 设置表头数据
     * @param array $data 生成的表格数据
     * @param bool $type 文件类型,true为Xlsx,false为Xls,默认为true
     * @param string $fileName 文件名,默认为数据
     */
    protected function export($header = [], $data = [], $type = true, $fileName = "数据")
    {
        // 实例化类
        $preadsheet = new Spreadsheet();
        // 创建sheet
        $sheet = $preadsheet->getActiveSheet();
        // 生成表头字母
        $letter = [];
        $n = 0;
        for ($i = 'A'; $i <= 'Z'; $i++) {
            if ($n<count($header)){
                $letter[] = $i;
            }else{
                break;
            }
            $n++;
        }
        // 循环设置表头数据
        foreach ($header as $k => $v) {
            // 解决长数字自动转科学计数法
            if(is_numeric($v) && strlen($v) > 11){
                $sheet->setCellValueExplicit($letter[$k].'1',$v,'s');
            }

            $sheet->setCellValue($letter[$k].'1', $v);
        }
        // 生成数据
        $sheet->fromArray($data, null, "A2");
        // 样式设置
        $sheet->getDefaultColumnDimension()->setWidth(12);
        // 设置下载与后缀
        if ($type) {
            header("Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            $type = "Xlsx";
            $suffix = "xlsx";
        } else {
            header("Content-Type:application/vnd.ms-excel");
            $type = "Xls";
            $suffix = "xls";
        }
        // 激活浏览器窗口
        header("Content-Disposition:attachment;filename=$fileName.$suffix");
        //缓存控制
        header("Cache-Control:max-age=0");
        // 调用方法执行下载
        $writer = IOFactory::createWriter($preadsheet, $type);
        // 数据流
        $writer->save("php://output");
    }
}

调用

$excel = new Excel();

// 导出
$header = ['姓名','性别'];
$data = [['小王','男'],['小李','男']];
$excel->export($header,$data);

// 导入
$data = $excel->importExcel('/storage/picture/20221222/77d80064c35db092c8124a13a7f6fcd5.xlsx');
if(is_array($data)){
    print_r($data);
}else{
    echo $data;
}

]]>
0 https://www.zzwws.cn/archives/6389/#comments https://www.zzwws.cn/feed/tag/PHP/
MySQL 小数类型 https://www.zzwws.cn/archives/6386/ https://www.zzwws.cn/archives/6386/ Wed, 28 Dec 2022 15:53:00 +0800 悠悠楠杉 定点数decimal
能够保证数据精确的小数(小数部分可能不精确,超出长度会四舍五入),整数部分一定精确
decimal(M, D), M表示总长度,最大值不能超过65,D代表小数部分长度,最长不能超过30

浮点型
又称为精度类型,是一种可能丢失精度的数据类型,数据可能不那么准确

float 单精度类型
4字节存储,7位精度,表示数据范围比整数大得多
float 表示不指定小数位的浮点数
float(M, D)表示一共存储M个有效数字,其中小数部分占D位

double 双精度类型
8个字节存储,表示范围更大,精度有15位左右
double 表示不指定小数位的浮点数
double(M, D)表示一共存储M个有效数字,其中小数部分占D位

如何选择
当需要存储的小数对精度要求不高时,可以选择FLOAT单精度浮点型,可以节省内存空间,提高计算速度。
当需要进行高速数学计算、科学计算、卫星定位计算等对精度要求较高时,可以选择DOUBLE双精度浮点型。
当需要进行精确计算,如工资结算、转账打款等财务类型的数据,可以选择DECIMAL定点型。

]]>
0 https://www.zzwws.cn/archives/6386/#comments https://www.zzwws.cn/feed/tag/PHP/
VSCode实用插件 https://www.zzwws.cn/archives/6370/ https://www.zzwws.cn/archives/6370/ Sat, 19 Nov 2022 14:10:00 +0800 悠悠楠杉 一、必备插件(web前端/PHP)

Chinese(中文)

HTML Snippets(代码提示)

HTML CSS Support(智能提示CSS类名以及id)

Auto Close Tag(自动闭合标签)

Auto Rename Tag(自动重命名 HTML 标签的开始和结束标签)

CSS Peek(选择某个 class 或者 id 名称按住Ctrl键+鼠标左键可以直接定位到该名称的CSS的位置)

Markmap(思维导图神器,.md文档编辑窗口的右上角就会多一个预览的图标Open as markmap,当然也可手动打开命令面板,输入Open as markmap)

css-auto-prefix(自动添加 CSS 私有前缀)

JavaScript (ES6) code snippets(智能提示与快速输入)

jQuery Code Snippets(jQuery代码智能提示)

px to rem & rpx & vw (cssrem)(px转换成rem,Font Size:填写设计稿的宽度/10)
需要在head引用lib-flexible:https://zhizun.lanzouy.com/iq8cDzuud2f

<script>
    if(window.screen.width >= 850){// 设置最大的字体大小,PC端显示,放到head
        document.getElementsByTagName('html')[0].style.fontSize = '85px';
    }
</script>

PHP Intelephense(PHP代码提示工具)

open in browser(快速打开html文件到浏览器预览)

Prettier - Code formatter(文件格式化,可配置自动格式化)

Vetur(官方钦定Vue插件)

Vue Language Features(默认的vue文件在vs code里全部是一样的文字,且不能点击。该插件让vue文件的内容有了颜色区分,同时支持点击相对路径文件的跳转)

Preview on Web Server(html文件保存,浏览器自动刷新,右键选择vscode-preview-server: Launch on browser,启动浏览器,需要使用本地web服务器,去掉右上角刷新提示:<style>#__bs_notify__{ display: none!important; }</style>

二、效率神器

Bracket Pair Colorizer(括号做颜色区分)

Browser Preview(VSCode里面打开浏览器)

REST Client(接口调试)

Partial Diff(文件比较)

Npm Intellisense(自动完成导入语句中的npm模块)

Path Intellisense(快速引入文件)

Color Highlight(设置 CSS 颜色的样式)

Project Dashboard(项目仪表板插件)

CodeSnap(代码截图插件)

Path Autocomplete(路径自动完成)

IntelliCode(提供智能的代码建议,默认支持 Python、TypeScript/JavaScript、React 和 Java)

ES7 React/Redux/GraphQL/React-Native snippets(语法智能提示,React 开发者必备)

Live SASS Compiler(可以将 SASS 或 SCSS 文件实时编译或转译为 CSS 文件)

Remote-SSH(SSH 服务器的远程机器作为开发环境)

Debugger for chrome(微软开发的插件,调试 JS 代码,可以设置断点、逐步执行代码、调试动态添加的脚本等)

Live Server(实时加载功能的小型服务器)

Minify(压缩html、css、js文件,安装后按F1再输入Minify)

Regex Previewer(实时预览正则表达式的效果)

HTML Boilerplate(一键生成 HTML 模板)

wakatime(编程时间及行为跟踪统计)

any-rule(常用正则大全)

Image preview(预览图片)

Tabnine(多语言的插件,自动完成代码的输入)

Settings Sync(配置同步到云端,登录账号也会同步扩展)

Codelf(提供很多建议的命名,选中文本再右键点击Codelf)

Highlight Matching Tag(突出显示匹配的开始和/或结束标签)

Turbo Console Log(快速添加 console.log 信息,js debug 必备,ctrl + alt + l 选中变量之后,使用这个快捷键生成 console.log,alt + shift + c 注释所有 console.log,alt + shift + u 启用所有 console.log,alt + shift + d 删除所有 console.log)

Sort lines(对当前文本排序)

Data Preview(预览数据文件)

三、Git集成

GitHub Pull requests( 查看和管理GitHub拉取请求和问题)

Git Graph(Git 图形化显示和操作)

GitLens(快速查看更改行或代码块的对象)

GitHistory(可查看和搜索git日志以及图形和详细信息)

四、美化

GitHub Theme(黑白两款皮肤)

vscode-icons(漂亮的目录树图标主题)

Better Align(代码优雅排版)

Better Comments(丰富注释颜色)

vscode-json(处理 JSON 文件)

Prettier(格式化插件支持React)

Material Theme(集成了多种主题皮肤)

Material Icon Theme(扁平化的主题图标库)

Beautify(右键鼠标一键格式化)

五、代码规范

change-case(变量命名规范)

JavaScript Booster(代码改进)

ESlint(严谨的规范书写)

TSLint(书写规范)

Code Spell Checker(拼写检查程序)

koroFileHeader(生成文件头部注释和函数注释)

Error Lens(代码检查(错误、警告、语法问题)进行突出显示)

EditorConfig for VS Code(代码风格统一)

六、装X神器

Markdown All in One(书写Markdown)

vscode-drawio(画流程图)

Polacode-2020(转化成一张逼格满满的图片)

Live Share(与他人实时进行协作式编辑和调试)

Markdown Preview Enhanced(在 VSCode 里编写 Markdown,支持预览)

]]>
0 https://www.zzwws.cn/archives/6370/#comments https://www.zzwws.cn/feed/tag/PHP/
ThinkPHP6使用扩展类库 https://www.zzwws.cn/archives/6369/ https://www.zzwws.cn/archives/6369/ Wed, 16 Nov 2022 10:06:45 +0800 悠悠楠杉 在使用thinkphp6时,经常要引用第三方类库,比如upload.php类,在框架根目录下的 extend 目录称为 扩展类库目录,用于存放一些自定义的类,只要符合自动加载的规范(命名空间、类名、文件名),就可以拿来直接使用。

1. extend 目录的直接子内容
假设在 extend 目录下创建一个 Upload.php 文件,如果是 extend 目录的直接子内容则不需要添加命名空间

<?php

class Upload
{
    
}

此时可以在控制器中直接使用 \Upload 类,特别注意命名空间

2. 带层级的类
假设在 extend/file 目录下创建一个 Upload.php 文件,此时需要添加命名空间

<?php

namespace file;

class Upload
{
    
}

此时可以在控制器中直接使用 \file\Upload 类

// 测试
dump(new \Upload());
dump(new \file\Upload());
]]>
0 https://www.zzwws.cn/archives/6369/#comments https://www.zzwws.cn/feed/tag/PHP/
PHP实现文件缓存 https://www.zzwws.cn/archives/6368/ https://www.zzwws.cn/archives/6368/ Mon, 14 Nov 2022 14:26:00 +0800 悠悠楠杉 Cache.class.php

<?php
class Cache
{

    /**
     * 缓存目录
     * @var
     */
    private $cache_dir;

    /**
     * @param $cache_dir
     * @throws Exception
     */
    public function __construct($cache_dir)
    {
        $this->cache_dir = $cache_dir;
        if (!is_dir($cache_dir)) {
            $make_dir_result = mkdir($cache_dir, 0755, true);
            if ($make_dir_result === false) throw new Exception('Cannot create the cache directory');
        }
    }


    /**
     * 根据key获取值,会判断是否过期
     * @param $key
     * @return mixed
     */
    public function get($key)
    {
        $cache_data = $this->getItem($key);
        if ($cache_data === false || !is_array($cache_data)) return false;

        return $cache_data['data'];
    }

    /**
     * 添加或覆盖一个key
     * @param $key
     * @param $value
     * @param $expire
     * @return mixed
     */
    public function set($key, $value, $expire = 0)
    {
        return $this->setItem($key, $value, time(), $expire);
    }

    /**
     * 设置包含元数据的信息
     * @param $key
     * @param $value
     * @param $time
     * @param $expire
     * @return bool
     */
    private function setItem($key, $value, $time, $expire)
    {
        $cache_file = $this->createCacheFile($key);
        if ($cache_file === false) return false;

        $cache_data = array('data' => $value, 'time' => $time, 'expire' => $expire);
        $cache_data = json_encode($cache_data);

        $put_result = file_put_contents($cache_file, $cache_data);
        if ($put_result === false) return false;

        return true;
    }

    /**
     * 创建缓存文件
     * @param $key
     * @return bool|string
     */
    private function createCacheFile($key)
    {
        $cache_file = $this->path($key);
        if (!file_exists($cache_file)) {
            $directory = dirname($cache_file);
            if (!is_dir($directory)) {
                $make_dir_result = mkdir($directory, 0755, true);
                if ($make_dir_result === false) return false;
            }
            $create_result = touch($cache_file);
            if ($create_result === false) return false;
        }

        return $cache_file;
    }

    /**
     * 判断Key是否存在
     * @param $key
     * @return mixed
     */
    public function has($key)
    {
        $value = $this->get($key);
        if ($value === false) return false;

        return true;
    }

    /**
     * 加法递增
     * @param $key
     * @param int $value
     * @return mixed
     */
    public function increment($key, $value = 1)
    {
        $item = $this->getItem($key);
        if ($item === false) {
            $set_result = $this->set($key, $value);
            if ($set_result === false) return false;
            return $value;
        }

        $check_expire = $this->checkExpire($item);
        if ($check_expire === false) return false;

        $item['data'] += $value;

        $result = $this->setItem($key, $item['data'], $item['time'], $item['expire']);
        if ($result === false) return false;

        return $item['data'];
    }

    /**
     * 减法递增
     * @param $key
     * @param int $value
     * @return mixed
     */
    public function decrement($key, $value = 1)
    {
        $item = $this->getItem($key);
        if ($item === false) {
            $value = 0 - $value;
            $set_result = $this->set($key, $value);
            if ($set_result === false) return false;
            return $value;
        }

        $check_expire = $this->checkExpire($item);
        if ($check_expire === false) return false;

        $item['data'] -= $value;

        $result = $this->setItem($key, $item['data'], $item['time'], $item['expire']);
        if ($result === false) return false;

        return $item['data'];
    }

    /**
     * 删除一个key,同时会删除缓存文件
     * @param $key
     * @return mixed
     */
    public function delete($key)
    {
        $cache_file = $this->path($key);
        if (file_exists($cache_file)) {
            $unlink_result = unlink($cache_file);
            if ($unlink_result === false) return false;
        }

        return true;
    }

    /**
     * 清除所有缓存
     * @return mixed
     */
    public function clear()
    {
        return $this->delTree($this->cache_dir);
    }

    /**
     * 递归删除目录
     * @param $dir
     * @return bool
     */
    function delTree($dir)
    {
        $files = array_diff(scandir($dir), array('.', '..'));
        foreach ($files as $file) {
            is_dir("$dir/$file") ? $this->delTree("$dir/$file") : unlink("$dir/$file");
        }
        return rmdir($dir);
    }

    /**
     * 根据key获取缓存文件路径
     *
     * @param  string $key
     * @return string
     */
    protected function path($key)
    {
        $parts = array_slice(str_split($hash = md5($key), 2), 0, 2);
        return $this->cache_dir . '/' . implode('/', $parts) . '/' . $hash;
    }

    /**
     * 获取含有元数据的信息
     * @param $key
     * @return bool|mixed|string
     */
    protected function getItem($key)
    {
        $cache_file = $this->path($key);
        if (!file_exists($cache_file) || !is_readable($cache_file)) {
            return false;
        }

        $cache_data = file_get_contents($cache_file);
        if (empty($cache_data)) return false;
        $cache_data = json_decode($cache_data, true);
        if ($cache_data) {
            $check_expire = $this->checkExpire($cache_data);
            if ($check_expire === false) {
                $this->delete($key);
                return false;
            }
        }

        return $cache_data;
    }

    /**
     * 检查key是否过期
     * @param $cache_data
     * @return bool
     */
    protected function checkExpire($cache_data)
    {
        $time = time();
        $is_expire = intval($cache_data['expire']) !== 0 && (intval($cache_data['time']) + intval($cache_data['expire']) < $time);
        if ($is_expire) return false;

        return true;
    }
}

使用方法

include('Cache.class.php');
$cache = new Cache($_SERVER['DOCUMENT_ROOT'].'/cache');

// 添加或覆盖
$cache->set('name','admin',3600);// 过期时间默认为0,不限制

// 获取
$cache->get('name');

// 删除
$cache->delete('name');

// 清空
$cache->clear();
]]>
0 https://www.zzwws.cn/archives/6368/#comments https://www.zzwws.cn/feed/tag/PHP/
PHP生成文件并下载文件 https://www.zzwws.cn/archives/6367/ https://www.zzwws.cn/archives/6367/ Fri, 04 Nov 2022 14:33:00 +0800 悠悠楠杉 <?php header("Content-Type: application/octet-stream"); $filename = "1.txt"; $content = '这里是需要生成文件的内容'; $ua = $_SERVER["HTTP_USER_AGENT"]; $encoded_filename = urlencode($filename); $encoded_filename = str_replace("+", "%20", $encoded_filename); if (preg_match("/MSIE/", $ua)) { header('Content-Disposition: attachment; filename="' . $encoded_filename . '"'); } else if (preg_match("/Firefox/", $ua)) { header('Content-Disposition: attachment; filename*="' . $filename . '"'); } else { header('Content-Disposition: attachment; filename="' . $filename . '"'); } echo $content; ]]> 0 https://www.zzwws.cn/archives/6367/#comments https://www.zzwws.cn/feed/tag/PHP/ PHP cookie加密登录与验证 https://www.zzwws.cn/archives/6366/ https://www.zzwws.cn/archives/6366/ Wed, 19 Oct 2022 22:15:00 +0800 悠悠楠杉 想要简单一点的可以用session,但session是创建会话,也会创建文件,这样文件会越来越多,会有些影响,所以用cookie会更好一点!

<?php
/**
 * cookie加密登录与验证
 * @param array $userInfo 用户信息
 * @param bool $validate 是否为验证或者填入token值验证,默认为false
 * @param int $expiresTime 过期时间,默认为1天
 * @param string $tag token标签,默认为zz_token
 * @return bool|string
 */
function zz_login($userInfo, $validate = false, $expiresTime = 1, $tag = 'zz_token')
{
    $salt = zz_salt();
    $host = $_SERVER['HTTP_HOST'];
    if (!$salt) {
        return false;
    }
    if (!$validate) {
        try {
            $expiresTime = time() + 3600 * 24 * $expiresTime;
            $token = base64_encode(json_encode(['userInfo' => $userInfo, 'domain' => $host, 'expiresTime' => $expiresTime, 'code' => md5(json_encode($userInfo) . $host . $expiresTime . $salt)]));
            setcookie($tag, $token, $expiresTime, '/');
            return $token;
        } catch (Exception $e) {
            return false;
        }
    } else {
        if($validate === true){
            if (empty($_COOKIE[$tag])) {
                return false;
            }
            $arr = json_decode(base64_decode($_COOKIE[$tag]), true);
        }else{
            $arr = json_decode(base64_decode($validate), true);
        }
        if (empty($arr['userInfo']) || empty($arr['domain']) || $arr['domain'] != $host || empty($arr['code']) || empty($arr['expiresTime']) || $arr['expiresTime'] <= time()) {
            return false;
        }
        return $arr['code'] === md5(json_encode($arr['userInfo']) . $host . $arr['expiresTime'] . $salt);
    }
    return true;
}

/**
 * 生成安全码
 * @return string
 */
function zz_salt()
{
    $root = $_SERVER['DOCUMENT_ROOT'];
    $file = $root.'/salt.php';
    if(is_file($file)){
        include($file);
        if(empty($salt) || empty($saltRoot) || $saltRoot != $root){
            $salt = rand_str(20,true);
            file_put_contents($file,"<?php \r\n\$salt = '{$salt}';\r\n\$saltRoot = '{$root}';");
        }
    }else{
        $salt = rand_str(20,true);
        file_put_contents($file,"<?php \r\n\$salt = '{$salt}';\r\n\$saltRoot = '{$root}';");
    }
    return $salt;
}

/**
 * 生成随机字符串
 * @param int $num 字符串位数,默认为6
 * @param bool $special 使用特殊字符,默认为false
 * @return string
 */ 
function rand_str($num = 6,$special = false)
{
    $str = 'abcedfghjkmnpqrstuvwxyzABCEDFGHJKMNPQRSTUVWXYZ0123456789';
    if($special){
        $str .= '!@#$%^&*';
    }
    return substr(str_shuffle($str), 0, $num);
}

// 登录
$userInfo = ['id' => 1,'username' => 'admin'];
zz_login($userInfo);

// 验证
if(zz_login('',true)){
    echo '登录';
}else{
    echo '未登录';
}

// 获取用户信息
$arr = json_decode(base64_decode($_COOKIE['zz_token']),true);
print_r($arr['userInfo']);
]]>
0 https://www.zzwws.cn/archives/6366/#comments https://www.zzwws.cn/feed/tag/PHP/
PHP快速导出大量数据到CSV https://www.zzwws.cn/archives/6365/ https://www.zzwws.cn/archives/6365/ Mon, 10 Oct 2022 14:01:48 +0800 悠悠楠杉 <?php //让程序一直运行 set_time_limit(0); //设置程序运行内存 ini_set('memory_limit', '128M'); $fileName = '数据'; header('Content-Encoding: UTF-8'); header("Content-type:application/vnd.ms-excel;charset=UTF-8"); header('Content-Disposition: attachment;filename="' . $fileName . '.csv"'); //打开php标准输出流 $fp = fopen('php://output', 'a'); //添加BOM头,以UTF8编码导出CSV文件,如果文件头未添加BOM头,打开会出现乱码。 fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF)); //添加导出标题 fputcsv($fp, ['姓名', '年龄', '地区']); $page = 1;//当前页数 $limit = 5000; //每次导出数量 while(1==1){ $limit_offset = ($page - 1) * $limit; $data = $this->where($where)->order('id desc')->limit($limit_offset,$limit)->select()->toArray(); if(!$data){ break; } foreach ($data as $v) { fputcsv($fp, $v); } //达到导出数量就刷新缓冲区 ob_flush(); flush(); $page++; } ]]> 0 https://www.zzwws.cn/archives/6365/#comments https://www.zzwws.cn/feed/tag/PHP/ PHP面向对象的链式调用方式 https://www.zzwws.cn/archives/6350/ https://www.zzwws.cn/archives/6350/ Thu, 21 Jul 2022 11:20:03 +0800 悠悠楠杉 实现起来也还蛮简单的,只需要在每个方法最后返回$this就可以了

<?php
class wc
{
    public function __construct($who)
    {
        echo "{$who}准备去上厕所了";
    }

    public function go()
    {
        echo "1.跑出了教室";
        return $this;
    }

    public function action($ss)
    {
        echo $ss . "2.到了厕所,开始尿尿";
        return $this;
    }

    public function back()
    {
        echo "3.尿尿结束,回到教室";
        return $this;
    }
}

$xm = new wc("小明");
$xm->go()->action("<br>")->back();

]]>
0 https://www.zzwws.cn/archives/6350/#comments https://www.zzwws.cn/feed/tag/PHP/