分类 ThinkPHP 下的文章

评论表

idarticle_idparent_id(string)
130
231
331_2
432
531_2_3

模型操作

删除 id = 1 的1 级文章及下级所有文章
Article::where('id', 1)->delete();
Article::where('parent_id', 'like', '1%')->delete();
这样和 id = 1 的所有相关文章就删除了
删除这些文章下的评论就用观察者就行了



第一步:

习惯将CDN文件下载到本地,保存至静态目录中,注意保留版本号。

<!-- 引入 css -->
<link href="https://cdn.jsdelivr.net/npm/@wangeditor/editor@latest/dist/css/style.css" rel="stylesheet">
<!-- 引入 js -->
<script src="https://cdn.jsdelivr.net/npm/@wangeditor/editor@latest/dist/index.min.js"></script>

第二步:

直接上 HTML代码吧:

<div class="layui-row">
            <div class="layui-col-md12">
                <div class="layui-form-item">
                    <label class="layui-form-label">正文:</label>
                    <div class="layui-input-block">
                        <textarea name="content" id="content" style="display: none"></textarea>
                        <div id="toolbar-container"></div>
                        <div id="editor-container" style="height: 300px;border:1px solid #dddddd"></div>
                    </div>
                </div>
            </div>
        </div>


第三步:

注意从官方拷贝js代码时,要注意javascript与typescript的修改。
直接上 JS代码。

// 渲染富文本编辑器
const { createEditor, createToolbar } = window.wangEditor;
// 编辑器配置
const editorConfig = {MENU_CONF: {}};
// 图片上传
editorConfig.MENU_CONF['uploadImage'] = {
    // 表单字段名称
    fieldName: 'file',
    // 单个文件的最大体积限制,默认为 2M
    maxFileSize: 5 * 1024 * 1024, // 5M
    // 最多可上传几个文件,默认为 100
    maxNumberOfFiles: 5,
    // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
    allowedFileTypes: ['image/*'],
    // 小于该值就插入 base64 格式(而不上传),默认为 0
    base64LimitSize: 5 * 1024, // 5kb
    // 自定义参数
    meta: {
        from: 'editor', //标志是从编辑器上传
    },
    // 上传图片的配置
    server: '<?=route("upload.image")?>',
};
// 默认提示文字
editorConfig.placeholder = '请输入内容'
editorConfig.onChange = (editor) => {
    // 当编辑器选区、内容变化时,即触发
    //console.log('content', editor.children)
    //console.log('html', editor.getHtml())
    document.getElementById('content').value = editor.getHtml();
}


// 工具栏配置
const toolbarConfig = {}

// 创建编辑器
const editor = createEditor({
    html: document.getElementById('content').value,
    selector: '#editor-container',
    config: editorConfig,
    mode: 'simple' // 或 'simple' 参考下文
})
// 创建工具栏
const toolbar = createToolbar({
    editor,
    selector: '#toolbar-container',
    config: toolbarConfig,
    mode: 'simple' // 或 'simple' 参考下文
})

最后:

截图如下。

333333.png

1.composer安装阿里云OSS SDK

composer require aliyuncs/oss-sdk-php

2.控制器里面引用

use OSS\Core\OssException;

use OSS\OssClient;

use OSS\Core\OssUtil; 

2.上传代码逻辑

//        接收文件数据
    $file = request()->file('img');

// 取出文件名截取后缀

    $name = $file->getOriginalName();
    $suffix = strchr($name,'.');

// 阿里云配置

    $accessKeyId = "LTAI5t88SfZ5yhH4Sgu1u3gt";
    $accessKeySecret = "vbLBZWvzazGZvJpPap20ZyKDoBbdq2";
    // Endpoint以杭州为例,其它Region请按实际情况填写。
    $endpoint = "oss-cn-shanghai.aliyuncs.com";
    // 设置存储空间名称。
    $bucket= "*";
    // 设置文件名称。
    //这里是由sha1加密生成文件名 之后连接上文件后缀
    $object = sha1(date('YmdHis', time()) . uniqid()) . $suffix;
    $url = 'http://test.caotengfei.xyz/'.$object;
    // <yourLocalFile>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
    $filePath = $file->getPathname();
    $options = array(
        OssClient::OSS_CHECK_MD5 => true,
        OssClient::OSS_PART_SIZE => 1,
    );

    try{
        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
        //返回uploadId。uploadId是分片上传事件的唯一标识,您可以根据uploadId发起相关的操作,如取消分片上传、查询分片上传等。
        $uploadId = $ossClient->initiateMultipartUpload($bucket, $object);
    } catch(OssException $e) {
        printf(__FUNCTION__ . ": initiateMultipartUpload FAILED\n");
        printf($e->getMessage() . "\n");
        return ;
    }
    print(__FUNCTION__ . ": initiateMultipartUpload OK" . "\n");

    $partSize = 10 * 1024 * 1024;
    $uploadFileSize = filesize($filePath);
    $pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize);
    $responseUploadPart = array();
    $uploadPosition = 0;
    $isCheckMd5 = true;
    foreach ($pieces as $i => $piece) {
        $fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
        $toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
        $upOptions = array(
            // 上传文件。
            $ossClient::OSS_FILE_UPLOAD => $filePath,
            // 设置分片号。
            $ossClient::OSS_PART_NUM => ($i + 1),
            // 指定分片上传起始位置。
            $ossClient::OSS_SEEK_TO => $fromPos,
            // 指定文件长度。
            $ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
            // 是否开启MD5校验,true为开启。
            $ossClient::OSS_CHECK_MD5 => $isCheckMd5,
        );
        // 开启MD5校验。
        if ($isCheckMd5) {
            $contentMd5 = OssUtil::getMd5SumForFile($filePath, $fromPos, $toPos);
            $upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
        }
        try {
            // 上传分片。
            $responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions);
        } catch(OssException $e) {
            printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} FAILED\n");
            printf($e->getMessage() . "\n");
            return;
        }
        printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} OK\n");
    }
// $uploadParts是由每个分片的ETag和分片号(PartNumber)组成的数组。
        $uploadParts = array();
        foreach ($responseUploadPart as $i => $eTag) {
            $uploadParts[] = array(
                'PartNumber' => ($i + 1),
                'ETag' => $eTag,
            );
        }
    try {
        // 执行completeMultipartUpload操作时,需要提供所有有效的$uploadParts。OSS收到提交的$uploadParts后,会逐一验证每个分片的有效性。当所有的数据分片验证通过后,OSS将把这些分片组合成一个完整的文件。
        $ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts);
    }  catch(OssException $e) {
        printf(__FUNCTION__ . ": completeMultipartUpload FAILED\n");
        printf($e->getMessage() . "\n");
        return;
    }
        return json(['code'=>200,'msg'=>'成功','url'=>$url]);





报错完整信息为:

Deprecated: Method ReflectionParameter::getClass() is deprecated in /vendor/topthink/think-container/src/Container.php on line 450
Script @php think service:discover handling the post-autoload-dump event returned with error code 255

这是因为在PHP8.0以后反射类ReflectionParameter::getClass() 已弃用,变更为getType()
只要找到文件vendor/topthink/think-container/src/Container.php修改替换即可。
如下图:
QQ20220215-172931@2x.png

详情见:https://github.com/top-think/framework/commit/df4a07d2f51307a6fabdf75dc5b4b7f8b0ad8af8

1、xls
application/vnd.ms-excel
2、xlsx
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
3、ppt
application/vnd.ms-powerpoint
4、pptx
application/vnd.openxmlformats-officedocument.presentationml.presentation
5、doc
application/msword
6、docx
application/vnd.openxmlformats-officedocument.wordprocessingml.document
7、zip
application/x-zip-compressed
8、rar
application/x-zip-compressed
9、wmv
video/x-ms-wmv
10、mp3
audio/mpeg
11、mp4
video/mp4
12、gif
image/gif
13、jpg
image/jpeg
14、png
image/png
15、bmp
image/bmp
16、psd
application/octet-stream
17、ico
image/x-icon
18、7z
application/octet-stream
19、exe
application/octet-stream
20、avi
video/avi
21、rmvb
application/vnd.rn-realmedia-vbr
22、3gp
application/octet-stream
23、flv
application/octet-stream
24、wav
audio/wav
25、krc
application/octet-stream
26、lrc
application/octet-stream
27、txt
text/plain
28、pdf
application/pdf
29、chm
application/octet-stream
30、mdb
application/msaccess
31、sql
application/octet-stream
32、con
application/octet-stream
33、log
text/plain
34、dat
application/octet-stream
35、ini
application/octet-stream
36、php
application/octet-stream
37、html 和 htmhtm
text/html
38、ttf
application/octet-stream
39、fon
application/octet-stream
40、js
application/x-javascript
41、xml
text/xml
42、dll
application/octet-stream

转自:https://learnku.com/articles/60802

products商品表

字段名称 描述 类型 加索引缘由
id 自增长ID unsigned big int 主键
title SKU 名称 varchar
description SKU 描述 varchar
price SKU 价格 decimal
stock 库存 unsigne int
product_id 所属商品 id unsigne big int 外键

orders订单表

字段名称 描述 类型 加索引缘由
id 自增长ID unsigned big int 主键
no 订单流水号 varchar 唯一
user_id 下单的用户ID unsigned big int 外键
address JSON格式的收货地址 text
total_amount 订单总金额 decimal
remark 订单备注 text
paid_at 支付时间 datetime, null
payment_method 支付方式 varchar, null
payment_no 支付平台订单号 varchar, null
refund_status 退款状态 varchar
refund_no 退款单号 varchar, null 唯一
closed 订单是否已关闭 tinyint, default 0
reviewed 订单是否已评价 tinyint, default 0
ship_status 物流状态 varchar
ship_data 物流数据 text, null
extra 其他额外的数据 text, null

order_sku 订单项目名

字段名称 描述 类型 加索引缘由
id 自增长ID unsigned big int 主键
order_id 所属订单ID unsigned big int 外键
product_id 对应商品ID unsigned big int 外键
product_sku_id 对应商品SKU ID unsigned big int 外键
amount 数量 unsigned int
price 单价 decimal
rating 用户打分 unsigned int, null
review 用户评价 text
reviewed_at 评价时间 timestamp, null

答案:这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。

附:面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配。实际上也就是说,让不同的类设计不同的方法。这样代码就分散到一个个的类中去了。这样做的好处是降低了代码的复杂程度,使类可重用。
但是人们也发现,在分散代码的同时,也增加了代码的重复性。什么意思呢?比如说,我们在两个类中,可能都需要在每个方法中做日志。按面向对象的设计方法,我们就必须在两个类的方法中都加入日志的内容。也许他们是完全相同的,但就是因为面向对象的设计让类与类之间无法联系,而不能将这些重复的代码统一起来。
也许有人会说,那好办啊,我们可以将这段代码写在一个独立的类独立的方法里,然后再在这两个类中调用。但是,这样一来,这两个类跟我们上面提到的独立的类就有耦合了,它的改变会影响这两个类。那么,有没有什么办法,能让我们在需要的时候,随意地加入代码呢?这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。
一般而言,我们管切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点。有了AOP,我们就可以把几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为。
这样看来,AOP其实只是OOP的补充而已。OOP从横向上区分出一个个的类来,而AOP则从纵向上向对象中加入特定的代码。有了AOP,OOP变得立体了。如果加上时间维度,AOP使OOP由原来的二维变为三维了,由平面变成立体了。从技术上来说,AOP基本上是通过代理机制实现的。
AOP在编程历史上可以说是里程碑式的,对OOP编程是一种十分有益的补充。

https://www.iteye.com/blog/hejiajunsh-1776569

1.首先在http://open-doc.dingtalk.com/microapp/serverapi2/vzzrkv中下载PHP版本SDK。解压后文件目录如图:

111.jpeg

这里我只用到dingtalk中的文件,删除aliyun、QimenCloud目录,保留top目录Autoloader.phpTopSdk.php文件。

2、composer.json中:

"autoload": {
    "classmap": [
        "database"
    ],
    "files":[
        "app/Packages/taobao/TopSdk.php"
    ],
    "psr-4": {
        "App\\": "app/"
    }
 
}

别忘记:然后执行composer dump-autoload

3、执行完毕后,在Controller中就可以直接使用DingTalk SDK了。测试结果如下(注意要加‘ \ ’):

object(DingTalkClient)#276 (9) { ["gatewayUrl"]=> string(34) "http://eco.taobao.com/router/rest" ["format"]=> string(4) "json" ["connectTimeout"]=> NULL ["readTimeout"]=> NULL ["apiCallType"]=> string(4) "oapi" ["httpMethod"]=> string(4) "POST" ["checkRequest"]=> bool(true) ["apiVersion":protected]=> string(3) "2.0" ["sdkVersion":protected]=> string(25) "dingtalk-sdk-php-20161214" }

本文转载:https://blog.csdn.net/xiaoweite1/article/details/106175892

记录下:

<IfModule mod_rewrite.c>
  Options +FollowSymlinks -Multiviews
  RewriteEngine On

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
</IfModule>