使用docker安装mindoc文档管理系统

使用docker安装mindoc文档管理系统
一、docker安装
   1. docker -v (检测当前系统是否安装docker 安装后提示:Docker version 1.13.1, build 092cba3)
   2.apt-get update (更新ubuntu系统到最新软件包)
   3.apt-get install docker.io  (安装docker包)
   4.docker ps  (查看docker的容器状态)
   5.docker pull ubuntu  (docker安装ubuntu最新镜像)
   6.docker images (查看本地所有镜像)
   7.docker run -d -it –name=mindoc -p 8181:8181 ubuntu /bin/bash(name前面双横线)
   从docker下载ubuntu镜像(如下中的ubuntu表示镜像名,从docker软件库中去找),并启动镜像 -d 后台一直运行, -it 有交互窗口 –name=web1 为容器取名为web1,-p 80:80 将外部80端口映射到容器80端口(千前面是外部,后面是容器),/bin/bash shell环境
   8.docker exec -it mindoc /bin/bash  (进入容器web1,-it 保持交互式)
二、进入docker 容器 安装mindoc
   1.apt-get update (更新ubuntu系统到最新软件包)
   2.mkdir mindoc (创建mindoc安装目录)
   3.cd mindoc (进入目录)
   3.wget https://github.com/lifei6671/mindoc/releases/download/v0.10.1/mindoc_linux_amd64.zip  (如果无法使用wget命令 请执行[apt-get install wget]安装wget 最新mindoc下载地址 https://github.com/lifei6671/mindoc/releases)
   4.unzip mindoc_linux_amd64.zip (解压当前下载文件 如果无法使用unzip命令 请执行[apt-get install zip]安装zip)
   5.vi /etc/profileexport  新增环境变量
    export ZONEINFO=/mindoc/lib/time/zoneinfo.zip
    (上面操作完成后需要注销Linux才能使刚才的环境变量设置生效。如果你的服务器上没有安装golang程序请手动设置一个环境变量如下:键名为 ZONEINFO,值为MinDoc跟目录下的/mindoc/lib/time/zoneinfo.zip 绝对路径。上面操作完成后需要注销Linux才能使刚才的环境变量设置生效。)
   6.配置数据库
请将刚才解压目录下 conf/app.conf.example 重名为 app.conf:
cp conf/app.conf.example conf/app.conf
同时配置如下节点:
#数据库配置
db_adapter=mysql
#mysql数据库的IP
db_host=127.0.0.1
#mysql数据库的端口号一般为3306
db_port=3306
#刚才创建的数据库的名称
db_database=mindoc_db
#访问数据库的账号和密码
db_username=root
db_password=123456
7. ./mindoc_linux_amd64 install  (在 MinDoc 根目录下使用命令行执行如下命令,用于初始化数据库:程序会自动初始化数据库,并创建一个超级管理员账号:admin 密码:123456)
8.执行如下命令启动程序:
#修改可执行权限
chmod +x mindoc_linux_amd64
#启动程序
./mindoc_linux_amd64
此时访问 http://localhost:8181 就能访问 MinDoc 了。
9.apt-get install calibre (安装calibre  文档导出功能)
10.如果你不想用端口号访问 MinDoc 就需要配置一个代理了。
Nginx 代理的配置文件如下:
server {
   listen       80;
   #此处应该配置你的域名:
   server_name  webhook.iminho.me;
   charset utf-8;
   #此处配置你的访问日志,请手动创建该目录:
   access_log  /var/log/nginx/webhook.iminho.me/access.log;
   location / {
       try_files /_not_exists_ @backend;
   }
   # 这里为具体的服务代理配置
   location @backend {
       proxy_set_header X-Forwarded-For $remote_addr;
       proxy_set_header Host            $http_host;
       proxy_set_header   X-Forwarded-Proto $scheme;
       #此处配置 MinDoc 程序的地址和端口号
       proxy_pass http://127.0.0.1:8181;
   }
}
参考地址 https://github.com/lifei6671/mindoc/wiki/Linux-%E4%B8%8B%E5%AE%89%E8%A3%85%E5%92%8C%E9%85%8D%E7%BD%AE-MinDoc
项目地址 https://github.com/lifei6671/mindoc
官方地址 https://www.iminho.me/

php 获取当前浏览器语言 EN CN

/*获取客户端语言设置到session*/
public function clientLang()
{
    $languageValue = Yii::$app->session->get('language');
    if (!isset($languageValue))
    {
        //只取前4位,这样只判断最优先的语言。如果取前5位,可能出现en,zh的情况,影响判断。
        $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 4);
        if (preg_match("/zh-c/i", $lang)||preg_match("/zh/i", $lang))
            Yii::$app->session['language'] ='CN';
        else
            Yii::$app->session['language'] ='EN';
    }


}

Composer实现PHP中类的自动加载

本篇博客承接上一篇,学习一下Composer实现的PHP的类的自动加载方式。首先说明一下,Composer是PHP针对PHP语言的第三方的依赖管理工具,将工程所用到的依赖文件包含在composer.json文件中,使用composer install命令就可以将所使用对应库或者文件加载进工程里面。下面分两部分介绍composer的基础,分别是composer的依赖管理和自动加载。

依赖管理

在composer出现之前,如果咋PHP项目中需要第三方的依赖文件,则需要程序员将所需要的源代码拷贝进工程中或者将源代码对应的文件下载下来手动添加到工程中。如果所需要的依赖文件依赖于更多的第三方文件,则程序员会陷入拷贝依赖文件的黑洞中,费时费力不说,有可能还会出现一些失误,composer就是在这种情况下出现的用于减轻程序员的对于依赖管理的负担的工具。

Composer通过使用配置文件composer.json文件完成依赖管理。composer.json文件包含了项目的简单介绍、项目对于外界的库或文件的依赖。从composer.json的扩展名就可以看得出来,composer.json中的内容是按照json标准组织的。本篇博客集中在类的自动加载机制上,因此对于composer.json中关于项目的作者等相关信息的解释忽略不解释。

在composer中将本项目所需要的外部依赖包写在关键字require对应的值中,require键可以对应着多个所需要的包,各个不同的包之间用逗号分隔。假设项目需要一个外部依赖包monolog,下面是在compose.json文件中对于monolog包的依赖配置项:

1
2
3
4
5
{
    "require":{
        "monolog/monolog": "1.0.* @dev"
    }
}

如上所示,require关键字将会映射包的名称monolog和包的版本1.0.*。其中,包的名称有两部分组成,中间以“/”分隔,“/”之前代表的包的所有者,在Github上一般是代表的Github的用户名,“/”代表的是实际的包的名称。其中“/”之前的名称必须是唯一的,但是”/”之后的包的名称是可以存在重复的,例如“Jack/monolog”和“monolog/monolog”是可以共存的。而后面的”1.0.*”代表的是所依赖的包的版本,其中“*”代表的是“1.0”之下的任意一个版本,例如:1.0.1,1.0.2或者1.0.9等等。“@dev”代表了可以获取该包的开发版本。默认情况下,composer将获取所需要的包的最新的稳定版本,而不会考虑开发版本,因为开发版本一般是不太稳定的版本。但是,如果确定开发版本没有什么问题就可以加上“@dev”以允许获取开发的版本。如果没有加上“@dev”,而除了开发版本之外不存在别的版本的话,则composer加载依赖项出错。

在composer中配置好依赖的第三方的包之后,就可以使用composer install命令获取第三方的包了。运行成功之后就可以项目中就会出现vendor文件夹,vendor文件夹中会包含我们在require中所列出的monolog文件。

出了生成列在composer.json中关键字require值下的文件之外,成功运行composer install之后还会生成对应的composer.lock文件,该文件依据composer.json中的依赖项生成依赖包对应的版本。这里需要说明的是,在我们运行composer install的时候会首先判断是否存在着composer.lock文件。如果原本就存在这composer.lock文件,那么就会直接根据composer.lock中的版本下载对应的包,此时不再理会composer.json中的配置项。如果不存在composer.lock文件,则根据composer.json文件中的配置下载对应的版本,并生成composer.json对应的composer.lock文件。composer.lock又称为锁定文件,生成对应的composer.lock之后,composer.json和composer.lock共同对版本进行控制。有了composer.lock之后,及时有了新的版本也不会触发新版本的更新,除非手动使用composer update命令进行手动的更新。

开发环境下的依赖

  有的时候我们只是在开发的时候才会依赖于某个具体的包,但是在发行的版本中并不需要这样的包,为了达到这种要求可以使用require-dev引入开发环境下的包依赖。如下:

1
2
3
4
5
{
    "require-dev":{
        "xxxx/xxxx": "x.x.* @dev"
    }
}

自动加载类

通过composer.json或者composer.lock,所依赖的第三方库已经被下载下来了,那么在我们的项目中怎么使用这些第三方库呢?最简单的方式就是通过include或者require将所需要的类文件包含进来,但是这种方式需要我们自己去寻找所使用的类对应的类文件,这就存在和PHP语言中直接使用include和require加载所需要的类存在同样的弊端,一种比较简单的方式当然就是使用composer提供的类的自动加载机制了。类似于PHP的自动加载机制,composer提供了autoload实现类的自动加载。

成功运行composer install之后,只要调用生成的vendor目录下的autoload.php文件就可以调用通过composer.json加载的类了。以上面所述的项目中需要monolog包为例,通过可以通过下面的方式使用monolog包中的Logger类。

1
2
include "vendor/autoload.php";
$log = new Monolog\Logger("name");

当然,除了使用第三方库中提供的类之外,还可以使用自己的定义的类。Composer提供了autoload关键字用于加载我们自己提供的类,假如我们定义了一个有关测试的类,如下:

1
2
3
4
5
6
7
class ClassTest{
    public function test()
    {
        echo "hello world!";
    }
}

将该类放在lib目录下的ClassTest.php文件夹下面,那么怎么让composer加载自己定义的类呢?

1. 在composer.json中加入autoload关键字

1
2
3
"autoload":{
    "files":["lib/ClassTest.php"];
}

files键对应的值是一个数组且改值是相对于文件应用根目录的文件的路径。在composer.json中加入上述的关键字之后,在命令行下运行composer dump-autoload就可以让composer重建加载信息,那么就可以在其他的文件中使用这个类了。

上述所述的方法和PHP中直接使用include和require存在一样的弊端,每个类都需要重新书写加载文件,费时费力。

2. composer.json中加入classmap关键字

相比于每个类文件都需要加载一次的做法,使用classmap关键字,能够减少程序员的负担,只需要将文件所在的目录添加在classmap的值中即可,如下:

1
"classmap" : ["lib"]

其实这需要建立一种类名到类所在的文件的映射关系。当需要相应的类的时候,composer通过类名找到对应的类文件名,将相应的类include进来。但是这同样存在一个问题就是,每增加一个类都需要重新运行一次composer dump-autoload重新创建类名到文件之间的映射关系,从而将对应的类加载进来。虽然比files关键字节省了功夫,但是依然不能完全自动加载所需要的类。

3. 基于PHP规范的自动加载方式

  针对PHP这种编程语言,到目前FIG指定了五个规范,分别如下:

  • PSR0:自动加载;
  • PSR1:基本代码规范;
  • PSR2:代码样式规范;
  • PSR3:日志接口规范;
  • PSR4:自动加载规范;

看上去PSR4与PSR0是重复了,但是PSR4规范比较干净,可以看成PSR0规范的升级版。二者最重要区别在于:PSR0规范中,下划线会被转换为目录分隔符,但是PSR4中下划线不具有特殊的含义。二者都是通过特定的目录、文件名以及类名,实现快速查找到类文件,并将相应的类加载进来。

PSR0和PSR4要求有个命名的空间,对上述的ClassTest类做相应的修改如下:

1
2
3
4
5
6
7
8
9
<?php
namespace ClassTestLib;
class ClassTest{
    public function test()
    {
        echo "hello world!";
    }
}

那么对应的文件的路径应该改为\lib\ClassTestLib\ClassTest.php,此时修改composer.json中的autoload如下:

1
2
3
4
5
"autoload":{
    "psr-0":{
        "ClassTestLib":"lib/"
    }  
}

可能你发现psr0的值有一些奇怪,是的。在这里ClassTestLib代表的是命名空间,而”lib”是目录名。加载对应的类文件的时候,搜索的路径是lib/ClassTestLib,而不是ClassTestLib/lib,这是在书写composer.json的时候需要注意的一点。

如果命名空间中存在着“\”,则在书写对应的composer.json的时候需要在相应的“\”再添加一个“\”。例如,如果命名空间改为ClassTest\Lib,相应的对应与应用根目录的路径名称应该变为\lib\ClassTest\Lib\ClassTest.php,对应的composer.json中的autoload应该变为:

1
2
3
4
5
"autoload":{
    "psr-0":{
        "ClassTest\\Lib":"lib/"
    }  
}

 

小结:以上是关于composer的基本使用方法,后续在遇到相关的问题,和大家在一起学习。

php使用gearman进行任务分发

一、安装gearman

下载gearman源码包

1
https://launchpad.net/gearmand/+download

如: gearmand-1.1.12.tar.gz

下载php的gearman扩展包

1
http://pecl.php.net/package/gearman

如: gearman-1.1.2.tgz

安装gearman

1
2
3
4
5
> yum install boost-devel gperf libevent-devel libuuid-devel
> tar xf gearmand-1.1.12.tar.gz
> cd gearmand-1.1.12
> ./configure
> make && make install

安装gearman的php扩展(建议php版本不要过高,因为php7的gearman扩展目前还没有出来)

1
2
3
4
5
6
> yum install autoconf
> tar xf gearman-1.1.2.tgz
> cd gearman-1.1.2
> /data/php56/bin/phpize
> ./configure --with-php-config=/data/php56/bin/php-config
> make && make install

修改php.ini

1
> vi /data/php56/lib/php.ini

添加如下两项

1
2
extension_dir=/data/php56/lib/php/extensions/no-debug-zts-20131226/
extension=gearman.so

查看扩展

1
> /data/php56/bin/php -m

 

二、简单的使用gearman

gearman中请求的处理过程一般涉及三种角色:client->job->worker
其中client是请求的发起者
job是请求的调度者,用于把客户的请求分发到不同的worker上进行工作
worker是请求的处理者

比如这里我们要处理client向job发送一个请求,来计算两个数之和,job负责调度worker来具体实现计算两数之和。

首先我们编写client.php

1
2
3
4
5
6
7
8
9
10
11
12
<?php
//创建一个客户端
$client = new GearmanClient();
//添加一个job服务
$client->addServer('127.0.0.1', 4730);
//doNormal是同步的,等待worker处理完成返回结果
//建议不要使用do()了
$ret = $client->doNormal('sum', serialize(array(10, 10)));
if($ret) {
    echo '计算结果:', $ret, "\n";
}

再编写worker.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
//创建一个worker
$worker = new GearmanWorker();
//添加一个job服务
$worker->addServer('127.0.0.1', 4730);
//注册一个回调函数,用于业务处理
$worker->addFunction('sum', function($job) {
    //workload()获取客户端发送来的序列化数据
    $data = unserialize($job->workload());
    return $data[0] + $data[1];
});
//死循环
while(true) {
    //等待job提交的任务
    $ret = $worker->work();
    if ($worker->returnCode() != GEARMAN_SUCCESS) {
        break;
    }
}

我们先启动gearmand服务

1
2
> mkdir -p /usr/local/var/log
> gearmand -d

运行worker文件

1
> /data/php56/bin/php /data/worker.php

再运行client文件

1
> /data/php56/bin/php /data/client.php

结果如下:

 

三、gearman异步的处理任务

这里我们client向job发送一个发送邮件的请求,不等待请求完成,继续向下执行。

client.php代码如下:

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
30
31
<?php
//创建一个客户端
$client = new GearmanClient();
//添加一个job服务
$client->addServer('127.0.0.1', 4730);
//doBackground异步,返回提交任务的句柄
$ret = $client->doBackground('sendEmail', json_encode(array(
    'email' => 'test@qq.com',
    'title' => '测试异步',
    'body' => '异步执行好牛B的样子',
)));
//继续执行下面的代码
echo "我的内心毫无波动,甚至还想笑\n";
do {
    sleep(1);
    //获取任务句柄的状态
    //jobStatus返回的是一个数组
    //第一个,表示工作是否已经知道
    //第二个,工作是否在运行
    //第三和第四,分别对应完成百分比的分子与分母
    $status = $client->jobStatus($ret);
    
    echo "完成情况:{$status[2]}/{$status[3]}\n";
    if(!$status[1]) {
        break;
    }
} while(true);

worker.php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
//创建一个worker
$worker = new GearmanWorker();
//添加一个job服务
$worker->addServer('127.0.0.1', 4730);
//注册一个回调函数,用于业务处理
$worker->addFunction('sendEmail', function($job) {
    //workload()获取客户端发送来的序列化数据
    $data = json_decode($job->workload(), true);
    //模拟发送邮件所用时间
    sleep(6);
    echo "发送{$data['email']}邮件成功\n";
});
//死循环
//等待job提交的任务
while($worker->work());  

结果如下:

 

四、gearman并行的执行多个任务

我们如何并行的计算两个数的累加和? 通过addTask添加多个任务到队列,然后进行并行计算。

client.php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
//创建一个客户端
$client = new GearmanClient();
//添加一个job服务
$client->addServer('127.0.0.1', 4730);
//设置任务完成时的回调函数
$client->setCompleteCallback(function($task) {
    //获取由worker返回的数据
    echo $task->data(), "\n";
});
//计算1到500的累加和
//添加五个任务到队列
$client->addTask('sum', json_encode(array(1, 100)));
$client->addTask('sum', json_encode(array(100, 200)));
$client->addTask('sum', json_encode(array(200, 300)));
$client->addTask('sum', json_encode(array(300, 400)));
$client->addTask('sum', json_encode(array(400, 500)));
//运行队列中的任务,do系列不需要runTask()
$client->runTasks();

worker.php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
//创建一个worker
$worker = new GearmanWorker();
//添加一个job服务
$worker->addServer('127.0.0.1', 4730);
//注册一个回调函数,用于业务处理
$worker->addFunction('sum', function($job) {
    //workload()获取客户端发送来的序列化数据
    $data = json_decode($job->workload(), true);
    sleep(1);
    $sum = 0;
    for($ix = $data[0]; $ix < $data[1]; ++$ix) {
        $sum += $ix;
    }
    return $sum;
});
//死循环
//等待job提交的任务
while($worker->work());

我们开启5个worker工作进程,当运行客户端请求时,5个计算任务几乎是同时返回结果。

结果如下:

 

https://www.cnblogs.com/jkko123/p/6493282.html

关于GMT和UTC时间? php 关于时区 date gmdate date_default_timezone_set/get 终极答疑

关于GMT和UTC时间?

GMT+0800
Greenwich: [gri:nitf], 格林威治/格林尼治.是英国伦敦泰晤士河附近的一个小镇
Mean: adj. 自私的; n. 平均..
he is mean about money.
GMT就是格林威治平均/标准时间

什么叫本初子午线?

国外叫 : prime mer’idian.只是在中国内才叫本初-子午线. 只是国内的翻译这样怪怪的.
prime 被国人翻译为本初,
meridian本意是 经线的/全盛的, 顶点的:
he is “at the meridian of ” life.
he was “at the meridian of ” his power then.
而在中国, 子为北方, 午为南方, 子午即南北方向, 所以就把经线 “南北线” 翻译成了子午线.
因此, 子午线只是中国的叫法, 国外没有 “子午” 这种天干地支的说法的.

经纬线都是假想 (imaginary)出来的线, 赤道是天然的纬线.经线从理论上来说, 任何连接南北两极的圆线都可以作为
prime meridian, 比如中国清朝的时候,还提出了自己的prime meridian. 因此, 需要从无数的子午线中 人为
地选出一条作为”首子午线”. 因为英国皇家天文台(Greenwich天文台)最先测量经线的长度, 所以把经过 Greenwich 天文台
子午仪中心的子午线作为经线的起点, 即0度子午线, 本初子午线.

Greenwich Village = the Village不是在英国, 而是在美国纽约.

GMT 又叫 UT0
经过 “地轴摆动”修正后的时间 叫 UT1, UT2
由铯原子钟提供的时间叫 “国际原子时” :TAI
那么, 把以上的所有时间: UT0, 1,2 TAI综合精确计算 提供的 “世界协调时” 就叫 UTC .
UTC与真的太阳时的误差在0.9秒内.否则, 要由巴黎…发布 “闰秒”.
UTC: universal time coordinated.

通常在程序中, php和javascript, jquery中, 就认为GMT和UTC是一样的, 没有区别的.

而CST, 则有 多义/歧义 解释了.
可以是 美国或澳大利亚的 Central Standard Time(中部标准时间)
也可以是 中国或古巴的标准时间: China/Cuba Standard Time
而在不同的语言中, 如php, java, 和 javascript中, 解释器/编译器对CST的理解不同, 而出错.

所以, 在编程中, 尽量少用 CST.

php和js/jquery中对时间/时区的操作?

  • 获得时间的函数:
php是 $dt = time()
js/jq 是 var dt = new Date();

// php中的time()时获得GMT时间戳的秒数. 是两个GMT时间的差 : 是指当前GMT英国Greenwich 0 时区的GMT时间
// 和unix纪元的 时间差.  跟php系统设置的 时区无关!
  • 也就是说, php的time()函数, 在某一时刻, 比如现在这一时刻, 在地球上的任何地方都是相同的. 因为他们都是返回的在伦敦的Greenwich的GMT时间.而不是本地时间, 所以跟php的系统设置时区无关.

  • 对日期/时间的操作
js获得new Date()对象后, 有丰富的成员函数来进行操作, 如getMonth, getDate, getDay, toString,UTC()等等
  • 对php的时间操作, 主要是date和gmdate的格式化问题
echo date("Y-m-d H:i:s"); 
// date() 返回的是: 当前(这一刻 time()函数执行/返回时) GMT标准时间 的"本地化时间" 的自定义格式时间
// date()跟php系统设置的时区有关!
echo gmdate("Y-m-d H:i:s");
// gmdate() 返回的是: 当前(这一刻 time()函数执行/返回时) GMT标准时间  的自定义格式时间
// gmdate() 跟你现在所处的位置无关, 跟php系统设置的时区无关!

也就说, date()和gmdate()的区别, 仅仅在于 处理的时间 是不同的!
  • strtotime(“str”)
strtotime("str"): 返回 string给定时间的 所对应的GMT标准时间的 unix时间戳,
如果当前php系统的设置的时区不是GMT标准时区,则在应用strtotime(string)时,系统会自动把时间
string折算成相应的GMT标准时间, 然后计算这个时间的unix时间戳。跟php系统设置的时区有关

关于时区

地球(地球和太阳在宇宙中的相对位置,和人类历史文化的原因)是自西向东自转,东边比西边先看到太阳,
东边的时间也比西边的早. 东边时刻与西边时刻的差值不仅要以时计,而且还要以分和秒来计算,
这给人们带来不便.

为了克服时间上的混乱, 1884年 在华盛顿召开的一次国际经度会议(又称国际子午线会议)上,
规定将全球划分为24个时区.它们是中时区(零时区)、东1-12区,西1-12区.
每个时区横跨经度15度,时间正好是1小时.最后的东、西第12区各跨经度7.5度,以东、西经180度为界.
每个时区的中央经线上的时间就是这个时区内统一采用的时间,称为区时.相邻两个时区的时间相差1小时.

例如,我国东8区的时间总比泰国东7区的时间快1小时,而比日本东9区的时间慢1小时.
因此,出国旅行的人,必须随时调整自己的手表,才能和当地时间相一致.
凡向西走,每过一个时区,就要把表向前拨1小时(比如2点拨到1点);凡向东走,每过一个时区,就要把表向后拨1小时
(比如1点拨到2点).

实际上,世界上不少国家和地区都不严格按时区来计算时间.为了在全国范围内采用统一的时间,
一般都把某一个时区的时间作为全国统一采用的时间.
例如,我国把首都北京所在的东8区的时间作为全国统一的时间,称为北京时间.
而实际上, 我国整个面积范围共跨了5个时区.
又例如,英国、法国、荷兰和比利时等国,虽地处中时区,但为了和欧洲大多数国家时间相一致,则采用东1区的时间.

如何设置php中的时区? 两种方法

  1. 如果可以修改服务器, 就在服务器中修改phh.ini文件:
[Date]
; Defines the default timezone used by the date functions
date.timezone = Asia/Shanghai 或者 Asia/Chongqing 或者 PRC
// 注意, 没有北京 Asia/Beijng
// 更注意的是, 如果phi.ini中没有[Date] date.timezone的话, 就要自己手动添加.
  1. 如果没有权限 不能 修改服务器上的php.ini, 就用函数方法
// 一般,最好在初始化 文件中 写
// 或调用时间函数之前, 写
ini_set('date.timezone', 'Asia/Shanghai 或者Asia/Chongqing 或者PRC');
ini_set('date.timezone', 'Etc/GMT-8'); // 后面是 -8 减8 , 这个Etc是linux中的/etc目录吗? 那最好不用?
date_default_timezone_set('Asia/Shanghai 或者Asia/Chongqing 或者PRC');
使用date_default_timezone_get()就可以获得系统 当前设置的 时区.

或者, 不用设置时区, 直接手动调整时间:
在显示/输出时间时, 都统一处理:
不使用date()
统一使用gmdate(), 但是在时间上加上 8*3600 这么多秒 到time()上去!
  1. php 手册上说的: date_default_timezone_set自 PHP 5.1.0 起(此版本日期时间函数被重写了),
string date_default_timezone_get ( void )
本函数返回  "默认时区" ,使用如下“假定”的顺序: 

■用 date_default_timezone_set() 函数设定的时区(如果设定了的话) 

■TZ 环境变量(如果非空) 

■date.timezone 配置选项(如果设定了的话) 

■自己推测(如果操作系统支持) 

■如果以上选择都不成功,则返回 UTC 
string date/gmdate ( string $format [, int $timestamp ] )
返回将整数 timestamp 按照给定的格式字串而产生的字符串。
如果没有给出时间戳则使用 "本地" 当前时间。换句话说,timestamp 是可选的,默认值为 time()。 

如果没有给出时间戳则使用 “本地” 当前时间。换句话说,timestamp 是可选的,默认值为 time()。

<?php
// date_default_timezone_set('Asia/Chongqing');
// ini_set('date.timezone', 'PRC');
// ini_set('date.timezone', 'prc');

$tz = date_default_timezone_get();
echo "默认时区是: $tz";

/* 好像没有设置TZ  (timezone) 这个常量 */
if(defined('TZ')) echo TZ; 
echo "<br />";

echo time();
echo "<br />";
echo gmdate('Y-m-d H:i:s');
echo "<br />";
echo date('Y-m-d H:i:s');

?>

那么time()函数的内部实现, 是不是 通过网络去访问 Greenwich的” 相关时间服务器” 而得到的呢? 好像不是, 因为即使是断了网, 还是能够获得time()函数的值? 应该是通过 操作系统 去实现的??

原文地址

https://www.cnblogs.com/bkylee/p/5260296.html

jQuery图片裁剪插件jQuery-photoClip

一款支持手势的裁图插件插件

由于目前网上很难找到一款支持手势的裁图插件,因此自己动手写了一个。为了快速开发,依赖了很多其他的开源插件。不过目前仅解决需求即可。

依赖插件

  • [jquery.transit.js] 插件 (v1.4 中已经移除了对该插件的依赖)
  • [iscroll-zoom.js] 插件(由于原插件的zoom扩展存在几个bug,所以建议使用demo中提供的iscroll-zoom.js文件,本人已经将这些bug修复)
  • [hammer.js] 插件
  • [lrz.all.bundle.js] 插件

操作说明

在移动设备上双指捏合为缩放,双指旋转可根据旋转方向每次旋转90度

在PC设备上鼠标滚轮为缩放,每次双击则顺时针旋转90度

使用方法及参数配置简介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="clipArea"></div>
<input type="file" id="file">
<button id="clipBtn">截取</button>
<div id="view"></div>
<script src="js/jquery-2.1.3.min.js"></script>
<script src="js/hammer.min.js"></script>
<script src="js/iscroll-zoom.min.js"></script>
<script src="js/lrz.all.bundle.js"></script>
<script src="js/jquery.photoClip.min.js"></script>
<script>
var clipArea = new bjj.PhotoClip("#clipArea", {
    size: [260, 260], // 截取框的宽和高组成的数组。默认值为[260,260]
    outputSize: [640, 640], // 输出图像的宽和高组成的数组。默认值为[0,0],表示输出图像原始大小
    //outputType: "jpg", // 指定输出图片的类型,可选 "jpg" 和 "png" 两种种类型,默认为 "jpg"
    file: "#file", // 上传图片的<input type="file">控件的选择器或者DOM对象
    view: "#view", // 显示截取后图像的容器的选择器或者DOM对象
    ok: "#clipBtn", // 确认截图按钮的选择器或者DOM对象
    loadStart: function(file) {}, // 开始加载的回调函数。this指向 fileReader 对象,并将正在加载的 file 对象作为参数传入
    loadComplete: function(src) {}, // 加载完成的回调函数。this指向图片对象,并将图片地址作为参数传入
    loadError: function(event) {}, // 加载失败的回调函数。this指向 fileReader 对象,并将错误事件的 event 对象作为参数传入
    clipFinish: function(dataURL) {}, // 裁剪完成的回调函数。this指向图片对象,会将裁剪出的图像数据DataURL作为参数传入
});
</script>

Destroy

1
clipArea.destroy();

phpstorm 2017激活 2018/02/04日测试可用

1. 通过Licence Server 激活PHPStorm 2017.1:

  1. http://www.0-php.com:1017(可用,更新于20170621)2018/02/04测试可用

    http://idea.singee77.com/

    http://idea.lanyus.com/ (已被封杀)

    http://idea.qinxi1992.cn/ (测试时不可以)

2. 本地激活PHPStorm 2017.1(不上网):

  1. 加载文件LocalServer.zip
  2. 解压压缩文件,并选择与您的操作系统的名称的文件
  3. 我们给运行该文件的权限并运行该文件
  4. 选择一个许可证服务器,并在许可证服务器地址:指定地址 http://127.0.0.1:1017/
  5. 按下按钮OK

3. 直接用浏览器打开 http://idea.lanyus.com/

点击页面中的“获得注册码”,然后在注册时切换至Activation Code选项,输入获得的注册码一长串字符串,便可以注册成功了!(推荐用这种方式)

4. 若资金允许,请前往https://www.jetbrains.com/idea/buy/购买正版

实用的loading插件 一个兼容移动端pc以及ie10以上的loading插件

loading

一个兼容移动端pc以及ie10以上的loading插件

演示地址: http://www.daiwei.org/components/loading/

direction

方向,column纵向 row 横向

animateIn

进入类型,这里不需要引用animatecss(因为个人觉得loading效果不需要太花哨,默认fadeInNoTransform,其他设置都不会有动画效果)

title

loading的title名称 为” 则不显示

titleColor

title的文字颜色

name

loading的name名称 这算是唯一标识,重复的name的loading不会再生成,因此每次需要给一个name属性

type

loading显示的样式   是转动的小圆球 origin 还是图片 pic

discription

loading的描述  为” 则不显示

discColor

loading的描述颜色

loadingWidth

默认260 loading的宽度

loadingBg

默认 ‘rgba(0, 0, 0, 0.6)’ loading的背景色

borderRadius

默认12 loading的圆角

loadingMaskBg

默认 transparent loading的遮罩层背景色

zIndex

默认 1000001 loading的层级

圆形旋转的loading样式  (origin)

originDivWidth

默认 60 loading内部圆球区域的宽度

originDivHeight

默认 60 loading内部圆球区域的高度

originWidth

默认 8 小圆球的宽度

originHeight

默认 8 小圆球的高度

originBg

默认’#fefefe’ 小圆球的背景色

smallLoading

默认 false 是否显示更小一点的旋转小球效果

这是图片的样式   (pic)

imgSrc

默认的图片地址

imgDivWidth

默认 80 图片的宽度

imgDivHeight

默认 80 图片的高度

flexCenter

默认false, 是否用flex布局让loading-div垂直水平居中

flexDirection

默认’row’ row column flex的方向 横向 和 纵向

mustRelative

默认false 调用loading的元素是否规定relative

 

https://github.com/IFmiss/loading