thinkphp6 redis消息队列简单教程 --- 2021-06-09 - 简书

mikel阅读(546)

来源: thinkphp6 redis消息队列简单教程 — 2021-06-09 – 简书

thinkphp6 redis消息队列简单教程

  1. 安装 thinkphp-queue

composer require topthink/think-queue

也可指定版本:composer require topthink/think-queue:2.*

  1. 搭建消息队列的存储环境
    使用 Redis
    安装并启动 Redis 服务 看你个人使用的windows下还是linux下的redis服务(或者其他);可自行搭建(这里不做介绍)
  2. 配置消息队列的驱动
    根据选择的存储方式,在\app\config\queue.php这个配置文件中,添加消息队列对应的驱动配置

<?php

return [
    'default'     => 'redis',
    'connections' => [
        'sync'     => [
            'type' => 'sync',
        ],
        'database' => [
            'type'  => 'database',
            'queue' => 'default',
            'table' => 'jobs',
        ],
        'redis'    => [
            'type'       => 'redis',
            'queue'      => 'default',
            'host'       => '127.0.0.1',
            'port'       => 6379,
            'password'   => '',
            'select'     => 0,
            'timeout'    => 0,
            'persistent' => false,
        ],
    ],
    'failed'      => [
        'type'  => 'none',
        'table' => 'failed_jobs',
    ],
];

?>
  1. 消息的创建与推送
    我们在业务控制器中创建一个新的消息,并推送到 helloJobQueue 队列
    新增 \app\controller\Test.php 控制器,在该控制器中添加 actionWithHelloJob 方法

<?php
namespace app\controller;
use app\BaseController;
use think\facade\Queue;
use think\facade\Db;
class Test extends BaseController
{
    public function index()
    {
        echo 222;
    }
    /*
    * 测试队列action
    * */
    public function actionWithHelloJob(){
        // 1.当前任务将由哪个类来负责处理。
        // 当轮到该任务时,系统将生成一个该类的实例,并调用其 fire 方法
        $jobHandlerClassName  = 'app\index\job\Hello@fire';
        // 2.当前任务归属的队列名称,如果为新队列,会自动创建
        $jobQueueName     = "helloJobQueue";
        // 3.当前任务所需的业务数据 . 不能为 resource 类型,其他类型最终将转化为json形式的字符串
        // ( jobData 为对象时,需要在先在此处手动序列化,否则只存储其public属性的键值对)
        $jobData          = [ 'name' => 'test'.rand(), 'password'=>rand()] ;
        // 4.将该任务推送到消息队列,等待对应的消费者去执行
        $time2wait = strtotime('2021-06-09 11:51:00') - strtotime('now');  // 定时执行
        $isPushed = Queue::later($time2wait, $jobHandlerClassName , $jobData , $jobQueueName );
        // database 驱动时,返回值为 1|false  ;   redis 驱动时,返回值为 随机字符串|false
        if( $isPushed !== false ){
            echo date('Y-m-d H:i:s') . " a new Hello Job is Pushed to the MQ"."<br>";
        }else{
            echo 'Oops, something went wrong.';
        }
    }

}

除了 Queue::push( jobHandlerClassName , jobData , jobQueueName );这种方式之外,还可以直接传入 Queue::push( jobHandlerObject ,null , jobQueueName ); 这时,需要在 jobHandlerObject 中定义一个 handle() 方法,消息队列在执行到该任务时会自动反序列化该对象,并调用其 handle()方法。 该方式的缺点是无法传入自定义数据。

  1. 消息的消费与删除
    编写 Hello 消费者类,用于处理 helloJobQueue 队列中的任务
    新增 \app\job\Hello.php 消费者类(app目录下新建job目录,然后创建Hello.php文件),并编写其 fire() 方法

<?php
/**
 * 文件路径: \application\index\job\Hello.php
 * 这是一个消费者类,用于处理 helloJobQueue 队列中的任务
 */
namespace app\job;
use think\queue\job;
use think\facade\Db;

class Hello {
    /**
     * fire方法是消息队列默认调用的方法
     * @param Job            $job      当前的任务对象
     * @param array|mixed    $data     发布任务时自定义的数据
     */
    public function fire(Job $job,$data){
        // 如有必要,可以根据业务需求和数据库中的最新数据,判断该任务是否仍有必要执行.
        $isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data);
        if(!$isJobStillNeedToBeDone){
            $job->delete();
            return;
        }

        $isJobDone = $this->doHelloJob($data);

        if ($isJobDone) {
            //如果任务执行成功, 记得删除任务
            $job->delete();
        }else{
            if ($job->attempts() > 3) {
                //通过这个方法可以检查这个任务已经重试了几次了
                $job->delete();
                // 也可以重新发布这个任务
                //$job->release(2); //$delay为延迟时间,表示该任务延迟2秒后再执行
            }
        }
    }

    /**
     * 有些消息在到达消费者时,可能已经不再需要执行了
     * @param array|mixed    $data     发布任务时自定义的数据
     * @return boolean                 任务执行的结果
     */
    private function checkDatabaseToSeeIfJobNeedToBeDone($data){
        return true;
    }

    /**
     * 根据消息中的数据进行实际的业务处理
     * @param array|mixed    $data     发布任务时自定义的数据
     * @return boolean                 任务执行的结果
     */
    private function doHelloJob($data) {
        // 根据消息中的数据进行实际的业务处理...
        // test
        Db::name('admin')->insert([
            'name'=>$data['name'],
            'password'=>$data['password']
        ]);
        return true;
    }

}

  1. 发布任务
    在浏览器中访问 http://localhost/index.php/test/actionWithHelloJob 可以看到消息推送成功。
  2. 处理任务
    切换当前终端窗口的目录到项目根目录下,执行
    php think queue:work –queue helloJobQueue
    可以看到执行的结果类似如下:

    image.png

    同时打开 redis 可视化工具 Redis Desktop Manager (没有的话 可下载去安装,然后连接上你的redis,就可以查看到工具了)

    image.png

以上是我使用thinkphp6 做的操作!

作者:一位先生_
链接:https://www.jianshu.com/p/55a367ed0cde
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Thinkphp5 用ab压力测试工具测试高并发请求 - Edward1108 - 博客园

mikel阅读(541)

来源: Thinkphp5 用ab压力测试工具测试高并发请求 – Edward1108 – 博客园

上篇文章【Thinkphp5实现悲观锁】已介绍过thinkphp5使用悲观锁实现高并发的场景,这篇文章将实际测试下。

在shell里进入到apache的bin目录,输入以下url:

ab -n 100 -c 100 http://www.xyh.com/index/index/mySQL_unlock  【不加锁的情况,模拟100次请求,每次100个用户】

备注:如果提示socket: Too many open files (24),请执行ulimit -a,然后ulimit -n 1024。下图是我已经修改后的。

 

由于在本机测试,如果并发太大,机器报错,需要重新编译apache。我这里只是为了测试thinkphp加锁是否能满足业务需求,所以并发设为100个,用来测试即可。数据库的商品表,我把库存设为50个。正常情况应该是:goods商品表中库存total值为0,销量sell为50,orders订单表有50条记录。经过测试,发现不加锁的情况如下图:

库存tatol为3个,销量sell为47,orders订单表有49条记录。很明显这不符合实际的业务需求!(这还是100次并发的情况,如果几十万的并发,错误更加离谱。会直接给公司带来巨大的损失)

下面再看看加锁后的测试情况:

库存tatol为0个,销量sell为50,orders订单表有50条记录。符合预期,满足业务需求!

 redis并发锁 thinkphp5_Thinkphp5+Redis实现商品秒杀代码实例讲解_Mike昊的博客-CSDN博客

mikel阅读(651)

来源: (1条消息) redis并发锁 thinkphp5_Thinkphp5+Redis实现商品秒杀代码实例讲解_Mike昊的博客-CSDN博客

环境:wamp,redis

要求:安装WAMP,Redis,以及为PHP安装Redis扩展

秒杀功能大致思路:获取缓存列表的长度,如果长度(llen)等于0,就停止秒杀,即秒杀失败,如果长度大于0,则继续运行,先从缓存中移除一个元素(lpop),再进行数据库操作(添加订单表,商品库存数量减一),如果再进一个人秒杀,就再走一遍流程,循环往复。

一、安装Redis扩展

1.查看PHP版本信息

打开phpinfo.php,查看PHP版本,我的是PHP7.3.4,还有一个需要注意Architecture x64

 

2.下载扩展文件

根据自己环境,选择合适的版本

3.解压

解压下载的压缩包,并把php_redis.dll、php_redis.pdb和php_igbinary.dll、php_igbinary.pdb四个文件,移至自己PHP版本对应目录下的ext文件夹下E:\phpstudy_pro\Extensions\php\php7.3.4nts\ext

 

 

4.修改php.ini

添加如下代码:

extension=php_igbinary.dll

extension=php_redis.dll

如果有这两句可以把前面的分号删掉,没有就自己添加上,要注意顺序,php_igbinary.dll 要在php_redis.dll 前面

 

5.重启Apache

重启后,再运行phpinfo.php,查看是否安装成功

 

二、数据结构

一共三张表,ab_goods商品表,ab_order订单表,ab_log日志表

商品表

 

订单表

 

日志表 记录秒杀信息

 

三、代码

namespace app\index\controller;

use think\Controller;

use think\Db;

use think\cache\driver\Redis;

class Miaosha extends Controller

{
private $redis = null;

private $cachekey = null; //缓存变量名

private $basket = []; //私有数组,存放商品信息

private $store = 50;

/**

* 购物车初始化,传入用户id

*/

public function __construct()

{
parent::__construct();

$this->redis = new \Redis(); // 实例化

$this->redis->connect(‘127.0.0.1′,’6379’);

$this->redis->auth(‘zxf123456′);

}

/**

* 秒杀初始化

*/

public function Ms_init()

{
// 删除缓存列表

$this->redis->del($this->cachekey);

$len = $this->redis->llen($this->cachekey);

$count = $this->store – $len;

for ($i=0; $i < $count; $i++) {
// 向库存列表推进50个,模拟50个商品库存

$this->redis->lpush($this->cachekey,1);

}

echo “库存初始化完成:”.$this->redis->llen($this->cachekey);

}

/**

* 秒杀入口

*/

public function index()

{
$id = 1; //商品编号

if (empty($id)) {
// 记录失败日志

return $this->writeLog(0,’商品编号不存在’);

}

// 计算库存列表长度

$count = $this->redis->llen($this->cachekey);

// 先判断库存是否为0,为0秒杀失败,不为0,则进行先移除一个元素,再进行数据库操作

if ($count == 0) { //库存为0

$this->writeLog(0,’库存为0′);

echo “库存为0”;

exit;

}else{
// 有库存

//先移除一个列表元素

$this->redis->lpop($this->cachekey);

$ordersn = $this->build_order_no(); //生成订单

$uid = rand(0,9999); //随机生成用户id

$status = 1;

// 再进行数据库操作

$data = Db::table(‘ab_goods’)->field(‘count,amount’)->where(‘id’,$id)->find(); //查找商品

if (!$data) {
return $this->writeLog(0,’该商品不存在’);

}

$insert_data = [

‘order_sn’ => $ordersn,

‘user_id’ => $uid,

‘goods_id’ => $id,

‘price’ => $data[‘amount’],

‘status’ => $status,

‘addtime’ => date(‘Y-m-d H:i:s’)

];

// 订单入库

$result = Db::table(‘ab_order’)->insert($insert_data);

// 自动减少一个库存

$res = Db::table(‘ab_goods’)->where(‘id’,$id)->setDec(‘count’);

if ($res) {
echo “第”.$count.”件秒杀成功”;

$this->writeLog(1,’秒杀成功’);

}else{
echo “第”.$count.”件秒杀失败”;

$this->writeLog(0,’秒杀失败’);

}

}

}

/**

* 生成订单号

*/

public function build_order_no()

{
return date(‘ymd’).substr(implode(NULL, array_map(‘ord’, str_split(substr(uniqid(), 7, 13), 1))), 0, 8);

}

/**

* 生成日志 1成功 0失败

*/

public function writeLog($status = 1,$msg)

{
$data[‘count’] = 1;

$data[‘status’] = $status;

$data[‘addtime’] = date(‘Y-m-d H:i:s’);

$data[‘msg’] = $msg;

return Db::table(‘ab_log’)->insertGetId($data);

}

}

四、压力测试

使用apache压力测试工具 AB 测试,模拟多用户秒杀商品,模拟60秒内发起3000个请求,并发600次,秒杀50个库存商品

AB测试相关参数说明

-r 指定接收到错误信息时不退出程序

-t 等待响应的最大时间

-n 指定压力测试总共的执行次数

-c 用于指定压力测试的并发数

1.初始化50个库存,运行ms_init方法

2.测试 命令行:

E:\phpstudy_pro\Extensions\Apache2.4.39\bin>ab -r -t 60 -n 3000 -c 1000 http://gouwuche.zxf/index/miaosha/index

 

3.检测数据库数据

 

 

日志表状态为1(秒杀成功)的数据有50人,订单表里的订单数也是50条,商品表里的商品数量变成了0(测试之前是50),商品秒杀成功完成!

如果不用redis而是直接用mySQL的话,商品表订单的数量count会变成负数,而秒杀成功的人数也多余50人,订单表里的订单数量也多余50条(新测),下面是直接用MySQL的例子;

public function SQLMs()

{
$id = 1; //商品编号

$count = 50;

$ordersn = $this->build_order_no(); //生成订单

$uid = rand(0,9999); //随机生成用户id

$status = 1;

// 再进行数据库操作

$data = Db::table(‘ab_goods’)->field(‘count,amount’)->where(‘id’,$id)->find(); //查找商品

// 查询还剩多少库存

$rs = Db::table(‘ab_goods’)->where(‘id’,$id)->value(‘count’);

if ($rs <= 0) {
$this->writeLog(0,’库存为0′);

}else{
$insert_data = [

‘order_sn’ => $ordersn,

‘user_id’ => $uid,

‘goods_id’ => $id,

‘price’ => $data[‘amount’],

‘status’ => $status,

‘addtime’ => date(‘Y-m-d H:i:s’)

];

// 订单入库

$result = Db::table(‘ab_order’)->insert($insert_data);

// 自动减少一个库存

$res = Db::table(‘ab_goods’)->where(‘id’,$id)->setDec(‘count’);

if ($res) {
echo “第”.$data[‘count’].”件秒杀成功”;

$this->writeLog(1,’秒杀成功’);

}else{
echo “第”.$data[‘count’].”件秒杀失败”;

$this->writeLog(0,’秒杀失败’);

}

}

}

到此这篇关于Thinkphp5+Redis实现商品秒杀的文章就介绍到这了,更多相关Thinkphp5+Redis实现商品秒杀内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
————————————————
版权声明:本文为CSDN博主「Mike昊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_35645230/article/details/113019644

C#报错:输入字符串格式不正确_pyy的博客-CSDN博客_输入字符串的格式不正确

mikel阅读(651)

来源: (1条消息) C#报错:输入字符串格式不正确_pyy的博客-CSDN博客_输入字符串的格式不正确

List<Model> data1 = list.Select(x => new Model { num = Convert.ToDecimal(x.PM25) }).OrderBy(x => x.num).ToList();

修改如下:

data = list.OrderBy(x => x.CO).Select(x => x.CO).ToList();
List<decimal> list3 = new List<decimal>();
decimal s3 = 0;
list3 = data.ConvertAll<decimal>(x => decimal.TryParse(x, out s3) == true ? s3 : s3);

附TryParse的使用方法如下:

https://blog.csdn.net/firetaker/article/details/5638914

Convert.ToDouble double.TryParse 使用方式比较

2010年06月01日 11:20:00 firetaker 阅读数:5258 标签: exceptionstring测试

 

 view plain copy

  1. static void Main(string[] args)
  2.       {
  3.          try
  4.          {
  5.             string str = “”;
  6.             // 如果当前str为空串,则出异常:输入字符串格式不正确
  7.             Console.WriteLine(Convert.ToDouble(str));
  8.          }
  9.          catch (Exception ex)
  10.          {
  11.             Console.WriteLine(ex.Message);
  12.          }
  13.          Console.ReadLine();
  14.       }

 

以上代码中出现的结果为:输入字符串格式不正确。因为传入的字符串为空,转换成double类型不成功

 

 view plain copy

  1. static void Main(string[] args)
  2.       {
  3.          try
  4.          {
  5.             string str = “123.123”;
  6.             // 如果当前str为空串,则出异常:输入字符串格式不正确
  7.             Console.WriteLine(Convert.ToDouble(str));
  8.          }
  9.          catch (Exception ex)
  10.          {
  11.             Console.WriteLine(ex.Message);
  12.          }
  13.          Console.ReadLine();
  14.       }

 

随便对str赋值一个合适的值,得到结果为:123.123

下面转换用另外一种方式处理:

第一种情况设置当前的str为空

 

 view plain copy

  1. static void Main(string[] args)
  2.     {
  3.        try
  4.        {
  5.           string str = “”;
  6.           double rst = 0.0;
  7.           Console.WriteLine(“转换结果为:” + double.TryParse(str, out rst));
  8.           Console.WriteLine(rst);
  9.        }
  10.        catch (Exception ex)
  11.        {
  12.           Console.WriteLine(ex.Message);
  13.        }
  14.        Console.ReadLine();
  15.     }

 

得到的结果为:

转换结果为:false

0

第二种情况:

 

 view plain copy

  1. static void Main(string[] args)
  2.       {
  3.          try
  4.          {
  5.             string str = “123.123”;
  6.             double rst = 0.0;
  7.             Console.WriteLine(“转换结果为:” + double.TryParse(str, out rst));
  8.             Console.WriteLine(rst);
  9.          }
  10.          catch (Exception ex)
  11.          {
  12.             Console.WriteLine(ex.Message);
  13.          }
  14.          Console.ReadLine();
  15.       }

 

 

得到的结果为:

转换结果为:true

123.123

 

由以上的测试结果可以看出。使用double.TryParse()做类型转换更安全

可以对返回值进行判断,也可以设置默认的返回值0

超详细!Android Studio 首次创建工程Sync出错解决办法_林辰的博客-CSDN博客_android studio sync失败

mikel阅读(1651)

来源: (1条消息) 超详细!Android Studio 首次创建工程Sync出错解决办法_林辰的博客-CSDN博客_android studio sync失败

Android Studio 首次创建工程Sync出错解决办法
因为课程需要,昨天安装了Android Studio(以下用AS表示)建立工程时出现了sync错误:

↑ sync failed出错

尝试了单独下载gradle文件的方法,使用国内镜像的方法,网上的方法五花八门看得我眼都花了😵
弄了大半天总算是搞定了…废话不多说,上干货!

解决方法
出现sync错误,其实也是解决AS gradle下载同步卡慢的问题,是因为每次建立或者打开工程时,AS会检测一遍文件是否缺少,正常来说AS可以帮我们自动下载,但是因为国内外服务器连接的问题,没办法正常下载,所以我们可以:

手动下载gradle包
打开AS,创建工程后,切换到Project视图

找到gradle–wrapper–gradle-wrapper.properties双击打开

文件路径:(注意gradle有不同的版本)

在右侧找到文件下载路径:distributionUrl=https://services.gradle.org/distributions/gradle-5.4.1-all.zip(把http://中的 \ 删掉)在浏览器中粘贴,等待下载任务弹出。或者到Gradle网站自行下载
下载完之后,在AS中打开设置

创建并更改gradle路径:

把下载好的gradle压缩包移到gradle路径下,并解压

打开解压后的gradle-5.4.1-all文件(注意路径变化)把.ok .lck文件复制到dists路径下

如下:

回到AS,重新sync

等待,sync成功✔

使用国内镜像
可以使用阿里云镜像解决下载失败的问题。只需要添加相应的url地址就可以下载。
切换视图,在Gradle Scripts中找到build.gradle,双击打开

添加两句代码:maven{ url ‘http://maven.aliyun.com/nexus/content/groups/public/’}
具体配置如下:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
maven{ url ‘http://maven.aliyun.com/nexus/content/groups/public/’}
google()
jcenter()

}
dependencies {
classpath ‘com.android.tools.build:gradle:3.5.2’

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
maven{ url ‘http://maven.aliyun.com/nexus/content/groups/public/’}
google()
jcenter()

}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
最后重新编译一下就OK了。

需要注意
很多国外软件的文件路径是不支持带有中文路径的。
下载的gradle版本要和AS中的一致。
————————————————
版权声明:本文为CSDN博主「请叫我林辰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45464418/article/details/112860163

解决下载Gradle失败问题:ERROR: Could not install Gradle distribution from ‘https://services.gradle.org/...... - 知乎

mikel阅读(969)

来源: 解决下载Gradle失败问题:ERROR: Could not install Gradle distribution from ‘https://services.gradle.org/…… – 知乎

1.项目场景:

第一次或升级安装 Android Studio 后创建项目或导入项目,下载Download gradle


2.问题描述:

新安装Android Studio3.5.2 后第一次创建项目是一只卡在下载https//services.gradle.org/dis 上。


3.原因分析:

网络不好、网络异常导致下载超时。

因为,这个资源是外网下载,所以很慢,慢到有时候一点击【Try Again】就直接提示下载失败!!!


4.解决方案:

4.1、直接关闭正在运行的Android Studio

4.2、通过别的方式,下载Gradle资源

例如方式一:copy【https://services.gradle.org/distributions/gradle-5.4.1-all.zip】这个链接,通过迅雷下载:

例如方式二:通过百度云等共享资源下载,自己百度一下,资源应该不少的。

4.3、将上面下载的资源,复制拷贝到对应版本的Gradle存放目录下

例如:C:\Users\Administrator.gradle\wrapper\dists\gradle-5.4.1-all\3221gyojl5jsh0helicew7rwx

4.4、重启Android Studio,耐心等待一小会儿 – >搞定!!!!

4.5、终于可以继续了!!!!


5.结束语

希望此文对大家有帮助,加油肝…吧!

哦,对了~~

感谢大家的阅读,更多精彩等待下次创作,你最大的支持就是:赞同+评论+收藏+喜欢+…,关注我。

另外,也欢迎大家关注同名宫塚豪: 聊者说

Android SDK的下载与安装 - HStranger - 博客园

mikel阅读(1164)

来源: Android SDK的下载与安装 – HStranger – 博客园

一、Android SDK简介

Android SDK(Software Development Kit,软件开发工具包)被软件开发工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合。它提供了 Android API 库和开发工具构建,测试和调试应用程序。简单来讲,Android SDK 可以看做用于开发和运行 Android 应用的一个软件。

二、下载SDK

1.目前官网上已经没有单独的SDK下载安装包了。谷歌官网推荐的是下载包含有Android SDK的Android Studio。官网下载地址

Android Studio是用来做安卓开发试调的官方退出的工具。但是谷歌官网在国内是无法访问

2.由于这个Android Studio 的安装包过大且官网下载需要FQ,而使用Appium 的时候实际上只需要用到SDK 工具而已。所以推荐大家去另外一个国内的Android 工具的下载网站androiddevtools下载。

①进入页面后点击【Android SDK 工具】按钮,然后在弹出的选择框内点击【SDK Tools】按钮,然后界面会自动跳转到SDK 的下载界面,选择适合自己的版本进行下载

 

 ②将下载后的安装包解压到相应的目录下,如下图:

三、安装Android 版本

①进入SDK的解压目录下,双击“SDK Manager.exe”打开SDK管理器

 

 ②在使用这个管理器的时候,需要使用FQ,才能进行下载安装;或者你也可以在上面推荐的那个下载SDK的国内安卓工具网站上下载适合你的版本的Android SDK 镜像,网站传送门

四、SDK环境配置 

在解压完成后,就可以开始配置环境变量了。方法和设置JAVA JDK的环境变量的方法类似。

“右键 我的电脑”—“属性”—“高级系统设置”—“环境变量”—“系统变量”—“新建”  SDK 需要对环境变量做如下更改(win 10):

1 创建ANDROID_HOME,值是你的刚刚SDK的解压目录,比如 E:\Android\android-sdk-windows

2.在新建完ANDROID_HOME之后,找到Path变量,然后双击打开Path 变量

将SDK的platform-tools和tool的路径添加到Path 变量内(这两个目录在你通过SDK Manager安装更新Android SDK Tools和Android SDK Platform-tools之后就会有了)
1 新建 %ANDROID_HOME%\platform-tools
2 新建 %ANDROID_HOME%\tools
3 新建 %ANDROID_HOME%\tools

 

五、创建并启动一个安卓模拟器

在安装了一个安卓SDK后,就可以创建一个对应版本的模拟器啦。

进入SDK的解压目录下,双击“AVD Manager.exe”打开安卓虚拟机管理器,如下图

然后点击“Create”按钮,打开创建安卓虚拟设备界面(如下图),然后输入各项信息进行虚拟设备创建。

不要选择超过电脑屏幕分辨率的Device,其他选项可参考上图,点击 “OK” 创建完成。

在 AVD Manage 工具中选中创建的Android虚拟机,点击 “Start…” 按钮启动(第一次启动会略慢,需要耐心的等一会儿),启动成功后如下图所示

解决php报错 chmod() has been disablde for security reasons 的教程 - 飞鸟慕鱼博客

mikel阅读(784)

来源: 解决php报错 chmod() has been disablde for security reasons 的教程 – 飞鸟慕鱼博客

今天有一个使用我用制作的zblog静态插件的用户来反馈一个 php 报错的问题,报错提示为“chomd() has been disablde for security reasons”,虽然很快就给解决了,但还是记录一下,方便以后查看。

php chmod() has been disablde for security reasons  错误详解

错误解析如下:

chmod() has been disablde for security reasons

复制

翻译:

出于安全原因,chmod() 函数已被禁用

复制

注释:由于 chmod() 可以更改文件的权限,所以很多运维在配置 php 时,都会禁用此函数。在 chmod() 函数被禁用的情况下,如果代码里出现此函数的调用,php 就会抛出上面的错误提示!

解决方法

1、虚拟机

一般的虚拟机管理后台都有 php.ini 的设置项目,下图以阿里云(万网)虚拟机为例,可以在后台的虚拟机管理面板中,chmod() 函数的设置项,启用即可!

如果你使用的虚拟机不支持函数的禁用设置,则可以咨询虚拟机的服务商,让他们帮助解决!

chmod() has been disablde for security reasons

2、云服务器

如果你使用的为云服务器,为自建的环境(例如宝塔面板,一些环境的集成等),则可以通过修改 php 的配置文件,php.ini 来解决此问题

(1)、找到 php 的配置文件 php.ini ,并打开

(2)、搜索 “disable_functions”,并定位到其所在行,不同的配置可能“disable_functions”的值不同,但都有一个 chmod 字符串。

chmod() has been disablde for security reasons

(3)、删除上面箭头所指的 “chmod”并保存

(4)、重启 php 服务 (如果重php服务不生效,就重启一下服务器)

 THINKPHP6 页面错误!请稍后再试~问题解决日记01_Dexx的博客-CSDN博客

mikel阅读(942)

来源: (1条消息) THINKPHP6 页面错误!请稍后再试~问题解决日记01_Dexx的博客-CSDN博客

##今天经过各大神教程学习发现对表的时候测试出来一句

页面错误!请稍后再试

自己检查好多问题表头啊结果现在就处于一个没错误提示的尴尬界面
通过搜查TP5的解决方式是换

config.php文件show_error_msg=false 改为True

同理TP6就一直找不到文件
搜代码发现TP6是更改

Config/app.php文件show_error_msg=false 改为True

问题解决!
总结
TP5跟TP6的位置不一样
现在能看到bug解决问题了!

这里感谢下给我道路指引的耕耕老师!
————————————————
版权声明:本文为CSDN博主「Dexx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43810144/article/details/110996687

Unknown character set: ‘utf8mb4‘_路窑的博客-CSDN博客

mikel阅读(630)

来源: (1条消息) Unknown character set: ‘utf8mb4‘_路窑的博客-CSDN博客

今天使用MySQL数据库运行SQL文件时遇到了这个错误:
Unknown character set: ‘utf8mb4’

错误原因:
我的Mysql是5.0版本的,版本比较低,而这个sql文件是在5.7版本的数据库中转储的,但是 MySQL 原字符集为utf8,从5.5开始采用的是utf8mb4。导致在我的数据库中无法识别这个字符集

解决方法:
使用记事本打开sql文件找到:set names utf8mb4这一行

将utf8mb4改为utf8即可

成功运行sql文件:

还是建议将mysql版本升级到5.7
————————————————
版权声明:本文为CSDN博主「路窑」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45800640/article/details/118103742