laravel使用aws笔记

一、引入composer



"aws/aws-sdk-php": "^3.137",
"league/flysystem-aws-s3-v3": "^1.0"

二、添加配置

's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),      #key
            'secret' => env('AWS_SECRET_ACCESS_KEY'), #秘钥
            'region' => env('AWS_DEFAULT_REGION'),  #区域
            'bucket' => env('AWS_BUCKET'),  #桶
            'root'  => '/images',   # 存储桶桶路径
            'visibility' => 'public',   # 是否公开
            'endpoint' => env('AWS_ENDPOINT'),   #源站
        ],

三、配置说明

AWS_BUCKET=test

AWS_ENDPOINT=http://s3.amazonaws.com/
注意:这里的endpoint是不需要桶名字的,最终源站就是test.s3.amazonaws.com 

四、使用案例

$bucketName = 'test';
        $client = S3Client::factory(array(
            "key" => "blog.phpfs.com",
            "secret" => "blog.phpfs.com",
            "region" => 'eu-central-1',
            "scheme" => "http",
            'version' => 'latest',
            'endpoint' => 'http://s3.amazonaws.com/',
        ));
        $file_Path = public_path("blog.phpfs.com/test.png");
        try {
            $Key = "images/img/test.png";
            $op = [
                'Bucket' => '',
                'Key'    => $Key,
                'Body'   => file_get_contents($file_Path),
                'ACL'    => 'public-read',
            ];
            $result = $client->putObject($op);
//            $result = $client->upload($bucketName, $Key,file_get_contents($file_Path), 'public-read');
            print_r($result);
        } catch (Aws\S3\Exception\S3Exception $e) {
            echo "There was an error uploading the file.\n";
            echo $e->getMessage();
        }

Session回收机制

文件存储
session.save_handler = files
session.save_path= “/var/lib/php/sessions”
session.gc_probability = 0
session.gc_divisor = 1000
session.gc_maxlifetime = 1800
文件存储清理的方案:
session.gc_divisor 与 session.gc_probability 合起来定义了在每个会话初始化时启动 gc(garbage collection 垃圾回收)进程的概率。此概率用 gc_probability/gc_divisor 计算得来。例如 1/100 意味着在每个请求中有 1% 的概率启动 gc 进程

Redis存储
session.save_handler = redis
session.save_path=”tcp://127.0.0.1:6379″

session.gc_maxlifetime = 1800

Redis存储清理的方案是按照gc_maxlifetime配置的时间来设定session 的ttl

MySQL数据表生成Wiki格式数据字典

<?php
$dbms='mysql';     //数据库类型
$host='localhost'; //数据库主机名
$dbName='joyous';    //使用的数据库
$user='test';      //数据库连接用户名
$pass='123456';          //对应的密码
$dsn="$dbms:host=$host;dbname=$dbName";

$table = array(
    't_user' => '用户表',
    't_user_info' => '用户扩展信息表',
 
);
try {
    $dbh = new PDO($dsn, $user, $pass); //初始化一个PDO对象
    $dbh->query('set names utf8');
    foreach ($table as $k => $v) {
        echo "### {$k}({$v})\n\n";
        $res = $dbh->query("SHOW FULL FIELDS FROM {$k}");
        $res->execute();
        $result = $res->fetchAll();
        echo "| 参数名称 | 类型 | 非空约束 | 备注说明|\n| ------ | ------ | ------ | ------ |\n";
        foreach ($result as $row)
        {
            echo "|{$row[0]}|{$row[1]}|{$row[3]}|{$row[8]}|\n";
        }
        echo "\n\n";
    }
} catch (PDOException $e) {
    echo $e->getMessage();
}

坑爹的BOM

场景:开发小程序使用wx.request请求数据时提示Cannot read property of ‘xxxx’ undefined……..

原因:request返回的数据会默认会经过JSON.parse函数转换为Object,如果返回内容带有BOM就会影响转换

解决办法:

1.服务器端返回数据去除BOM(一般的IDE都有这样的功能)

2.编写兼容代码(在小程序内wx.request设置dateType:’text’,然后将返回的res.data进行去除字符res.data.trim()处理之后调用JSON.parse转换)

小程序wx.uploadFile失败的问题排查记录

现象:部分安卓(华为meta9)下用canvas画图之后使用wx.canvasToTempFilePath保存文件,然后再使用wx.uploadFile上传到服务器,上传图片失败

尝试方案:

1、canvasToTempFilePath延迟执行(怀疑是不是生成图需要时间,就加了延迟执行) ,结果:还是不能上传

2、设定header(网上有说编码的问题,我设置了header)
 header: {
      ‘content-type’: ‘multipart/form-data’
    },
结果:还不能上传

3、服务器记录的日志当中看到华为上传的FILE是这样的

最终解决方案:

服务器端判断上传文件类型,通过file_put_contents写入到文件

结果:成功

备注:

这个图片导出同样是安卓机器,在小米5导出是这样的

而且华met9上是这样的

PHP取余的那些事

1、百分号取余

$val=9.45; 
$result=$val*100;
echo intval($result);   //这里输出944
echo $result%100;    //这里输出44
echo fmod(floatval($result),100);  //这里输出45

解释:因为php默认对变量进行取整进行取余运算的

2、取余溢出

<?php
$num1 = 1494313163777;
$num2 = 9999;
//直接计算取余会出错,出现负数 -8779
echo $num1 % $num2;

//解决方案:
$num1 = floatval($num1);
$luck_num = fmod($num1, $num2);
//显示38正确
echo $luck_num;

Composer

Composer是PHP中用来管理依赖(dependency)关系的工具。你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer会帮你安装这些依赖的库文件。

如果A依赖B的版本是1.0.0,如果C依赖B的版本是2.0.0,项目当中是否没导入同一包用不同版本的。

PHP的自动加载可以使用__autoload()和spl_autoload_register()两种机制,但官方推荐使用和spl_autoload_register
更多参考:http://php.net/manual/zh/language.oop5.autoload.php

Composer提供了四种自动加载的方式,分别是PSR-0、PSR-4、生成classmap以及直接包含files。
PSR-0要求目录名称和命名空间层层对应,会导致目录结构容易变得比较深。虽然已被官方废弃,但因为主流框架都已实现psr-0,因此composer仍然使用psr-0来向下兼容。按照PSR-0的规则,当试图自动加载 “Foo\Bar\Baz” 这个class时,那么会去寻找”src/Foo/Bar/Baz.php”。

psr-4方式,是composer推荐使用的一种方式,也是psr-0的替代方案,因为在PSR-0中目录结构要与命名空间层层对应,无法插入一个单独的目录。

classmap方式,则是通过配置指定的目录或文件,然后在Composer安装或更新时,它会扫描指定目录下以.php或.inc结尾的文件中的class,生成class到指定file path的映射,并加入新生成的 vendor/composer/autoload_classmap.php 文件中

files方式,就是手动指定供直接加载的文件

PHP反射机制

PHP反射机制它是用来导出或提取出关于类、方法、属性(私有保护等属性也能获取)、参数等的详细信息,包括注释。

<?php

class Test{
    public $var1 = 'var1';
    public $var2 = 'var2';
    private $var3 = 'var3';
    public function method1() {
        echo '1';
    }
    public function method2(){
        echo '2';
    }
    private function method3($v1, $v2, $v3) {
        echo '3' . $v1;
    }
}
print_r(get_class_methods('Test'));
print_r(get_class_vars('Test'));
//用反射类可以获得私有属性和私有方法
$ref = new ReflectionClass(new Test());
print_r($ref->getMethods());
print_r($ref->getProperties());

//执行私有方法
$ref = new ReflectionMethod('Test', 'method3');
$params  = $ref->getParameters();
$arg = [];
foreach ($params as $param) {
    if($param->getName()) {
        $arg[] = '参数1';
    }
}
//设置可见
$ref->setAccessible(true);
$ref->invokeArgs(new Test(), $arg);

更多内容参考:http://php.net/manual/zh/book.reflection.php

php使用elasticsearch

1.引入包
composer require elasticsearch/elasticsearch

2.DEMO参考

<?php
require_once './vendor/autoload.php';

use Elasticsearch\ClientBuilder;

$hosts = [
    [
        'host' => '192.168.56.201',
        'port' => '9200',
        'scheme' => 'http',
        //'user' => 'username',
        //'password' => 'password'
    ],
];
try {
    $client = ClientBuilder::create()->setHosts($hosts)->build();
    //创建index并设置mapping
    /*$params = [
        'index' => 'demo',  //索引名(相当于关系型mysql的数据库)
        'body' => [
            'settings' => [
                'number_of_shards' => 1,  //分片数
                'number_of_replicas' => 1, //副本分骗术
            ],
            'mappings' => [
                'm_type' => [
                    '_all' => [
                         'enabled' => 'false'
                    ],
                    '_routing' => [
                        'required' => 'true'
                    ],
                    'properties' => [ //文档类型设置(相当于mysql的数据类型)
                        'name' => [
                            'type' => 'string',
                            'store' => 'true'
                        ],
                        'age' => [
                            'type' => 'integer'
                        ]
                    ]
                ]
            ]
        ]
    ];
    $response = $client->indices()->create($params);
    print_r($response);//Array ( [acknowledged] => 1 [shards_acknowledged] => 1 )
    */
//    索引操作
//    $params = [
//        'index' => 'demo',
//    ];
//    $response = $client->indices()->delete($params);    //删除索引
//    print_r($response);//Array ( [acknowledged] => 1 )
    //$response = $client->indices()->getSettings($params);//获取索引设置信息
    //print_r($response);//Array ( [demo] => Array ( [settings] => Array ( [index] => Array ( [creation_date] => 1502246895144 [number_of_shards] => 5 [number_of_replicas] => 5 [uuid] => tW3DB-9FRQC2W-bwXl0fbg [version] => Array ( [created] => 5040199 ) [provided_name] => demo ) ) ) )
    //$response = $client->indices()->exists($params);   //检测索引是否存在
    //print_r($response);//1
    //$response = $client->indices()->getMapping($params);   //获取索引的mapping信息
    //print_r($response);//Array ( [demo] => Array ( [mappings] => Array ( [m_type] => Array ( [_all] => Array ( [enabled] => ) [_routing] => Array ( [required] => 1 ) [properties] => Array ( [age] => Array ( [type] => integer ) [name] => Array ( [type] => text [store] => 1 ) ) ) ) ) )
    
    //添加文档
//    $params = [
//        'index' => 'demo',
//        'type' => 'm_type',
//        'id' => '2',
//        'body' => [
//            'name' => 'demo',
//            'age' => 150
//        ],
//        'routing' => '/demo/m_type'
//    ];
//    $response = $client->index($params);
//    print_r($response);
  
    //删除文档
//    $params = [
//        'index' => 'demo',
//        'type' => 'm_type',
//        'id' => '2',
//        'routing' =>   '/demo/m_type'
//    ];
//    $response = $client->delete($params);
//    print_r($response);//Array ( [found] => 1 [_index] => demo [_type] => m_type [_id] => 1 [_version] => 2 [result] => deleted [_shards] => Array ( [total] => 2 [successful] => 2 [failed] => 0 ) )
    
    //修改文档
//    $params = [
//        'index' => 'demo',
//        'type' => 'm_type',
//        'id' => '2',
//        'body' => [
//            'doc' => [
//                'name' => 'demo22',
//                'age' => 130
//            ]
//        ],
//        'routing' =>   '/demo/m_type'
//    ];
//    $response = $client->update($params);
//    print_r($response);
    //获取文档并指定字段
//    $params = [
//        'index' => 'demo',
//        'type' => 'm_type',
//        'id' => '2',
//        '_source' => [
//            'age'
//        ],
//        'routing' =>   '/demo/m_type'
//    ];
//    $response = $client->get($params);
//    print_r($response);
//    $response = $client->getSource($params);
//    print_r($response);
    
    //高级搜索
//    $params = [
//        'index' => 'demo',
//        'type'  => 'm_type',
//        'routing' => '/demo/m_type',
//        'body' => [
//            'query' => [
//                'match' => [
//                    'age' => 130,
//                ]
//            ]
//        ]
//    ];
//    $response = $client->search($params);
//    print_r($response);
    
} catch (Exception $e) {
    echo $e->getMessage();
}

备注:如果提示routing_missing_exception则参数当中需要传递routing

参考:https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html