Linux下安装jdk1.8

在这里插入图片描述

一、安装准备
linux操作系统(CentOS 7.4 64位)
jdk1.8
xshell、xftp
二、安装步骤
1.下载jdk安装包
下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
操作系统多少位就下载多少位的jdk如图:

2.下载完成后把安装包上传到服务器,这里我用的是Xftp工具,对命令感兴趣的同学可以百度一下命令怎么上传到linux

在这里插入图片描述


3.命令行进行解压

tar -zxvf jdk-8u11-linux-x64.tar.gz
在这里插入图片描述


解压出来后可以看到jdk的文件夹了
4.进入/usr/目录下新建一个名为java的文件夹

命令:mkdir java
在这里插入图片描述


把刚刚解压出来的jdk移动到新创建的java文件夹下

mv /tools/jdk1.8.0_11/ /usr/java/
在这里插入图片描述


安装结束,接下来进行环境变量的配置

第三:环境变量配置
进入etc目录下通过vim命令进行编辑profile文件

vim profile

在末尾新增
export JAVA_HOME=/usr/java/jdk1.8.0_11
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}
在这里插入图片描述


修改完成后需要通过命令让配置文件立即生效

source /etc/profile
在这里插入图片描述


最后测试一下是否安装成功

javac
在这里插入图片描述
java -version
在这里插入图片描述


Linux安装jdk1.8完成

Linux平台安装MongoDB

MongoDB 提供了 linux 各个发行版本 64 位的安装包,你可以在官网下载安装包。

安装前我们需要安装各个 Linux 平台依赖包。

Red Hat/CentOS:

sudo yum install libcurl openssl

Ubuntu 18.04 LTS (“Bionic”)/Debian 10 “Buster”:

sudo apt-get install libcurl4 openssl

Ubuntu 16.04 LTS (“Xenial”)/Debian 9 “Stretch”:

sudo apt-get install libcurl3 openssl

MongoDB 源码下载地址:https://www.mongodb.com/download-center#community

这里我们选择 tgz 下载,下载完安装包,并解压 tgz(以下演示的是 64 位 Linux上的安装) 。

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-4.2.8.tgz    # 下载
tar -zxvf mongodb-linux-x86_64-ubuntu1604-4.2.8.tgz                                    # 解压

mv mongodb-src-r4.2.8  /usr/local/mongodb4                          # 将解压包拷贝到指定目录

MongoDB 的可执行文件位于 bin 目录下,所以可以将其添加到 PATH 路径中:

export PATH=<mongodb-install-directory>/bin:$PATH

<mongodb-install-directory> 为你 MongoDB 的安装路径。如本文的 /usr/local/mongodb4 。

export PATH=/usr/local/mongodb4/bin:$PATH

创建数据库目录

默认情况下 MongoDB 启动后会初始化以下两个目录:

  • 数据存储目录:/var/lib/mongodb
  • 日志文件目录:/var/log/mongodb

我们在启动前可以先创建这两个目录并设置当前用户有读写权限:

sudo mkdir -p /var/lib/mongo
sudo mkdir -p /var/log/mongodb
sudo chown `whoami` /var/lib/mongo     # 设置权限
sudo chown `whoami` /var/log/mongodb   # 设置权限

接下来启动 Mongodb 服务:

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

打开 /var/log/mongodb/mongod.log 文件看到以下信息,说明启动成功。

# tail -10f /var/log/mongodb/mongod.log
2020-07-09T12:20:17.391+0800 I  NETWORK  [listener] Listening on /tmp/mongodb-27017.sock
2020-07-09T12:20:17.392+0800 I  NETWORK  [listener] Listening on 127.0.0.1
2020-07-09T12:20:17.392+0800 I  NETWORK  [listener] waiting for connections on port 27017

MongoDB 后台管理 Shell

如果你需要进入 mongodb 后台管理,你需要先打开 mongodb 装目录的下的 bin 目录,然后执行 mongo 命令文件。

MongoDB Shell 是 MongoDB 自带的交互式 Javascript shell,用来对 MongoDB 进行操作和管理的交互式环境。

当你进入 mongoDB 后台后,它默认会链接到 test 文档(数据库):

$ cd /usr/local/mongodb4/bin
$ ./mongo
MongoDB shell version v4.2.8
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("2cfdafc4-dd56-4cfc-933a-187b887119b3") }
MongoDB server version: 4.2.8
Welcome to the MongoDB shell.
……

由于它是一个JavaScript shell,您可以运行一些简单的算术运算:

> 2+2
4
> 3+6
9

现在让我们插入一些简单的数据,并对插入的数据进行检索:

> db.runoob.insert({x:10})
WriteResult({ "nInserted" : 1 })
> db.runoob.find()
{ "_id" : ObjectId("5f069bdb4e02f8baf90f1184"), "x" : 10 }
> 

第一个命令将数字 10 插入到 runoob 集合的 x 字段中。如果要停止 mongodb 可以使用以下命令:

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown

也可以在 mongo 的命令出口中实现:

> use admin
switched to db admin
> db.shutdownServer()

更多安装方法可以参考官网:https://docs.mongodb.com/manual/administration/install-on-linux/

基于vue的实时视频流开发

背景:多个实时视频的介入

技术:hls.js的流媒体,支持格式已m3u8为主

解决了什么:多个实时视频长时间播放会有卡顿的情况

具体代码实现:

import Hls from 'hls.js'

  playVideo(id) {

      let  hls = new Hls();
      const _this = this
      let video = $("#camera-video")[0]
        if(Hls.isSupported()) {//查看浏览器是否支持
          hls.loadSource(this.videoSrc);//输入视频源
          hls.attachMedia(video);//添加到视频标签里
          hls.on(Hls.Events.MANIFEST_PARSED,function() {
            video.play();
          });
      this.hlsObj=hls;  }else if (video.canPlayType('application/vnd.apple.mpegurl')) { video.src = this.videoSrc; video.addEventListener('loadedmetadata',function() { video.play(); }); } },
销毁视频
destoryVideo() {
      this.$refs.cameraVideo.pause();
      this.hlsObj.destroy();
      this.hlsObj = null;
    }

mySql多表连接查询与union与union all用法

1.准备两个表

表a:

  结构:

复制代码
mysql> desc a;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name  | varchar(40) | NO   | PRI | NULL    |       |
| age   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
复制代码

  数据

表b:

  结构

复制代码
mysql> desc b;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| nameB | varchar(40) | YES  |     | NULL    |       |
| ageB  | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
复制代码

  数据:

2.进行连接查询测试:

(1)交叉连接(笛卡尔积)  cross join

复制代码
mysql> select * from a,b;  #第一种
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
| A2   |    2 | B1    |    1 |
| A1   |    1 | B2    |   22 |
| A2   |    2 | B2    |   22 |
+------+------+-------+------+
4 rows in set (0.00 sec)

mysql> select * from a cross join b;  #第二种
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
| A2   |    2 | B1    |    1 |
| A1   |    1 | B2    |   22 |
| A2   |    2 | B2    |   22 |
+------+------+-------+------+
4 rows in set (0.00 sec)

mysql> select a.*,b.* from a cross join b;  #第二种的又一个写法
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
| A2   |    2 | B1    |    1 |
| A1   |    1 | B2    |   22 |
| A2   |    2 | B2    |   22 |
+------+------+-------+------+
4 rows in set (0.00 sec)
复制代码

 (2)内连接    join 或 inner join(在笛卡尔积的基础上过滤)

  • 显示内连接

(1)不带条件的内连接

复制代码
mysql> select a.*,b.* from a inner join b on a.age=b.ageb;  #第一种 inner join
+------+------+-------+------+ | name | age | nameB | ageB | +------+------+-------+------+ | A1 | 1 | B1 | 1 | +------+------+-------+------+ 1 row in set (0.00 sec)
复制代码
复制代码
mysql> select a.*,b.* from a join b on a.age=b.ageb;  #第二种  join (默认是inner join)
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
+------+------+-------+------+
1 row in set (0.00 sec)
复制代码

三个表的显示内连接:

复制代码
SELECT
  a.*,
  b.*,
  c.*
FROM exampaper a
  INNER JOIN bigquestion b
  INNER JOIN exampaperquestion c
    ON a.paperId = b.paperId
      AND b.bigQuertionId = c.bigQuertionId
复制代码

四个表的显示内连接:

复制代码
SELECT
    train.trainingSchemaName,
    train.majorName,
    train.createTime,
    tc.*, course.*, type.*
FROM
    trainschemeinfo train
JOIN train_course tc ON train.trainingSchemeID = tc.trainningSchemeID
INNER JOIN t_course_base_info course ON tc.courseID = course.courseId
INNER JOIN coursetypeinfo type ON tc.typeNum = type.typeNum
WHERE
    tc.trainningSchemeID = '661ecb064b164d1ea133956f89beddb7'
复制代码

与之等价的隐士内连接:

复制代码
SELECT
    train.trainingSchemaName,
    train.majorName,
    train.createTime,
    tc.*, course.*, type.*
FROM
    trainschemeinfo train,
    train_course tc,
    t_course_base_info course,
    coursetypeinfo type
WHERE
    train.trainingSchemeID = tc.trainningSchemeID
AND tc.courseID = course.courseId
AND tc.typeNum = type.typeNum
AND tc.trainningSchemeID = '661ecb064b164d1ea133956f89beddb7'
复制代码

 (2)显示内连接带条件

复制代码
mysql> select a.*,b.* from a join b on a.age=b.ageb having a.name='A1';  #having从查出的数据中挑选满足条件的元祖
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
+------+------+-------+------+
1 row in set (0.00 sec)
  
mysql> select a.*,b.* from a join b on a.age=b.ageb where a.name='A1';  #where查询满足条件的元素
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
+------+------+-------+------+
1 row in set (0.00 sec)
复制代码
  • 隐士内连接:
复制代码
mysql> select * from a,b where a.age=b.ageb;  
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
+------+------+-------+------+
1 row in set (0.00 sec)

mysql> select * from a,b where a.age=b.ageb and a.name='A1';
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
+------+------+-------+------+
1 row in set (0.00 sec)

mysql> select * from a,b where a.age=b.ageb having a.name='A1';
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
+------+------+-------+------+
1 row in set (0.00 sec)
复制代码

  where是从本地磁盘查询满足条件的元素,having是从查出的数据中挑选满足条件的元素。执行权限   where>sum()..聚合函数>having

 (3)左外连接:(拿左边的匹配右边的,没有找到右边的为null)

复制代码
mysql> select * from a left join b on a.age = b.ageb;  #第一种 left join
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
| A2   |    2 | NULL  | NULL |
+------+------+-------+------+
2 rows in set (0.00 sec)

mysql> select * from a left outer join b on a.age = b.ageb;  #第二种 left outer join
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
| A2   |    2 | NULL  | NULL |
+------+------+-------+------+
2 rows in set (0.00 sec)
复制代码

(4)右外连接:(拿右边的匹配左边的,没有找到左边的为null)

复制代码
mysql> select * from a right join b on a.age = b.ageb;  #第一种  right join
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
| NULL | NULL | B2    |   22 |
+------+------+-------+------+
2 rows in set (0.00 sec)

mysql> select * from a right outer join b on a.age = b.ageb;  #第二种 right outer join
+------+------+-------+------+
| name | age  | nameB | ageB |
+------+------+-------+------+
| A1   |    1 | B1    |    1 |
| NULL | NULL | B2    |   22 |
+------+------+-------+------+
2 rows in set (0.00 sec)
复制代码

3.Union 和 union all  取两个表的并集测试

修改b表,加一条和a表重复的数据

b表数据:

a表数据:

(1)   union:   自动去掉重复元素

复制代码
mysql> select * from a union select * from b;
+------+------+
| name | age  |
+------+------+
| A1   |    1 |
| A2   |    2 |
| B1   |    1 |
| B2   |   22 |
+------+------+
4 rows in set (0.00 sec)
复制代码

 总结:

union:联合的意思,即把两次或多次查询结果合并起来。
要求:两次查询的列数必须一致
推荐:列的类型可以不一样,但推荐查询的每一列,想对应的类型以一样
可以来自多张表的数据:多次sql语句取出的列名可以不一致,此时以第一个sql语句的列名为准。
如果不同的语句中取出的行,有完全相同(这里表示的是每个列的值都相同),那么union会将相同的行合并,最终只保留一行。也可以这样理解,union会去掉重复的行。
如果不想去掉重复的行,可以使用union all。
如果子句中有order by,limit,需用括号()包起来。推荐放到所有子句之后,即对最终合并的结果来排序或筛选,可以对union之后的数据进行排序和分页等操作。

例如:采用union合并的多个表的数据的SQL

  需求是:为了显示学院、专业、班级树,但是这些信息不在一个月表,而且班级表中有专业编号,专业表中有学院编号。思路就是:分别从三个表中获取数据,然后采用union进行合并数据。

复制代码
SELECT
  classID   AS departNum,
  className AS departName,
  "class" AS departType,
  (SELECT
     majorID
   FROM t_major_base_info
   WHERE majorID = class.majorID) AS updepartNum
FROM t_class_base_info class
UNION 
SELECT majorID AS departNum,
    majorName AS departName,
    "major" AS departType,
      (SELECT
        collegeID   FROM t_college_base_info
   WHERE collegeID=major.collegeID) AS updepartNum
 FROM t_major_base_info major
UNION
SELECT collegeId AS departNum,
    collegeName AS departName,
    "college" AS departType,
    "000" AS updepartNum
    FROM t_college_base_info
复制代码

(2)    union all  保留重复元素

   UNION ALL 命令和 UNION 命令几乎是等效的,不过 UNION ALL 命令会列出所有的值。

复制代码
mysql> select * from a union all select * from b;
+------+------+
| name | age  |
+------+------+
| A1   |    1 |
| A2   |    2 |
| B1   |    1 |
| B2   |   22 |
| A1   |    1 |
+------+------+
5 rows in set (0.00 sec)
复制代码

总结:

  UNION 用于合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行。
  UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。
  同时,每条 SELECT 语句中的列的顺序必须相同.

  默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
  当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行

 注意:

1、UNION 结果集中的列名总是等于第一个 SELECT 语句中的列名
2、UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同

补充:今天在项目种用到了从多个表种查询数据把并且分页,实现过程是将所有表的名字传到dao,然后遍历表名字,一起添加条件(前提是需要查询的列名字相同):

复制代码
    public List<Map<String, Object>> getAllData(List<String> tableNames) {
        List<String> sqls = new ArrayList();
        StringBuilder sb = null;
        for (String tableName : tableNames) {
            sb = new StringBuilder();
            sb.append("select id,name from ");
            sb.append(tableName);
            sb.append(" where 1=1");
            sb.append(" and name = 'zhangsan'");
            sqls.add(sb.toString());
        }

        String sqlFinally = StringUtils.join(sqls, " union ");
        sqlFinally += "order by name limit 5,5";
        System.out.println(sqlFinally);

        /*Session session = getSessionFactory().openSession();
        SQLQuery sqlQuery = session.createSQLQuery(sqlFinally);
        sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return sqlQuery.list();*/
        return null;

    }
复制代码

测试:

复制代码
    public static void main(String[] args) {
        GroupDaoImpl g = new GroupDaoImpl();
        List tableNames = new ArrayList();
        tableNames.add("t1");
        tableNames.add("t2");
        tableNames.add("t3");
        g.getAllData(tableNames);
    }
复制代码

结果:

select id,name from t1 where 1=1 and name = 'zhangsan' union select id,name from t2 where 1=1 and name = 'zhangsan' union select id,name from t3 where 1=1 and name = 'zhangsan' order by name limit 5,5

【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】

网站或内容如何提交到百度收录

百度已经给站长提供了主动提交页面的代码:

<script>

(function(){    

var bp = document.createElement(‘script’);  

var curProtocol = window.location.protocol.split(‘:’)[0];    

if (curProtocol === ‘https’)

{  

bp.src = ‘https://zz.bdstatic.com/linksubmit/push.js’;   

 }    

else {

 bp.src = ‘http://push.zhanzhang.baidu.com/push.js’;   

 }    

var s = document.getElementsByTagName(“script”)[0];   

 s.parentNode.insertBefore(bp, s); })();

</script>

在php中判断一个字符串包含另一个字符串

方法一:用php的strpos() 函数判断字符串中是否包含某字符串的方法

if(strpos('Longway','way') !== false){ 
 echo '包含way';
}else{
 echo '不包含way';
}

方法二:使用了explode

用explode进行判断PHP判断字符串的包含代码如下:

<?php
  $url = "001a.gif";
  $str = "a";
  $con = explode($str,$url);
  if (count($con)>1):
  echo $url."中包含".$str;
  else:
  echo $url."中没有包含".$str; 
  endif;
?>

方法三:strstr

strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。
该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。

代码如下:

<?php
  /*如手册上的举例*/
  $email = 'user@example.com';
  $domain = strstr($email, '@');
  echo $domain;
?>

方法四:stristr

stristr() 函数查找字符串在另一个字符串中第一次出现的位置。
如果成功,则返回字符串的其余部分(从匹配点)。如果没有找到该字符串,则返回 false。

它和strstr的使用方法完全一样.唯一的区别是stristr不区分大小写.

多线程编程 – PHP 实现

多线程

线程

首先说下线程:

线程(thread) 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.

使用多线程主要是因为它在执行效率上有很大优势。由于线程是操作系统能够进行调度的最小单位

  • 一个多线程程序比单线程程序被操作系统调度的概率更大,所以多线程程序一般会比单线程程序更高效;
  • 多线程程序的多个线程可以在多核 CPU 的多个核心同时运行,可以将完全发挥机器多核的优势;

同时对比多进程程序,多线程有以下特点:

  • 线程的创建和切换的系统开销都比进程要小,所以一定程度上会比多进程更高效;
  • 线程天生的共享内存空间,线程间的通信更简单,避免了进程IPC引入新的复杂度。

适用场景

多线程的优化是很多,可是无脑使用多线程并不能提升程序的执行效率,因为线程的创建和销毁、上下文切换、线程同步等也是有性能损耗的,耗费时间可能比顺序执行的代码还多。如:

sumSmall是一个从1累加到50000的函数。

上图是在主线程内执行了三次 sumSmall 和三个线程分别执行 sumSmall ,再将结果同步到一个线程的时间对比,我们会发现只在主线程执行的时间反而更短,三个线程创建、切换、同步的时间远远大过了线程异步执行节省的时间。

而函数 sumLarge 从1累加到5000000,下图同一线程执行三次和三个线程执行的耗时:

这次,多线程终于有效率优势了。

是否使用多线程还需要根据具体需求而定,一般考虑以下两种情况:

  • I/O 阻塞会使操作系统发生任务调度,阻塞当前任务,所以代码中 I/O 多的情况下,使用多线程时可以将代码并行。例如多次读整块的文件,或请求多个网络资源。
  • 多线程能充分利用 CPU,所以有多处大计算量代码时,也可以使用多线程使他们并行执行,例如上文中后一个例子。

PHP中的多线程

PHP 默认并不支持多线程,要使用多线程需要安装 pthread 扩展,而要安装 pthread 扩展,必须使用 --enable-maintainer-zts 参数重新编译 PHP,这个参数是指定编译 PHP 时使用线程安全方式。

线程安全

多线程是让程序变得不安分的一个因素,在使用多线程之前,首先要考虑线程安全问题:

线程安全:线程安全是编程中的术语,指某个函数、函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。

在传统多线程中,由于多个线程共享变量,所以可能会导致出现如下问题:

  1. 存在一个全局数组$arr = array('a');;
  2. A 线程获取数组长度为1;
  3. B 线程获取数组长度为1;
  4. A 线程 pop 出数组元素 $a = array_pop($arr); $a = 'a';;
  5. B 线程也 pop 数组元素 $b = array_pop($arr); $a = null;;
  6. 此时 B 线程内就出现了灵异事件,明明数组长度大于0,或没有 pop 出东西;

PHP 实现

PHP 实现的线程安全主要是使用 TSRM 机制对 全局变量和静态变量进行了隔离,将全局变量和静态变量 给每个线程都复制了一份,各线程使用的都是主线程的一个备份,从而避免了变量冲突,也就不会出现线程安全问题。

PHP 对多线程的封装保证了线程安全,程序员不用考虑对全局变量加各种锁来避免读写冲突了,同时也减少了出错的机会,写出的代码更加安全。

但由此导致的是,子线程一旦开始运行,主线程便无法再对子线程运行细节进行调整了,线程一定程度上失去了线程之间通过全局变量进行消息传递的能力。

同时 PHP 开启线程安全选项后,使用 TSRM 机制分配和使用变量时也会有额外的损耗,所以在不需要多线程的 PHP 环境中,使用 PHP 的 ZTS (非线程安全) 版本就好。

类和方法

PHP 将线程 封装成了 Thread 类,线程的创建通过实例化一个线程对象来实现,由于类的封装性,变量的使用只能通过构造函数传入,而线程运算结果也需要通过类变量传出。

下面介绍几个常用的 Thread 类方法:

  • run():此方法是一个抽象方法,每个线程都要实现此方法,线程开始运行后,此方法中的代码会自动执行;
  • start():在主线程内调用此方法以开始运行一个线程;
  • join():各个线程相对于主线程都是异步执行,调用此方法会等待线程执行结束;
  • kill():强制线程结束;
  • isRunning():返回线程的运行状态,线程正在执行run()方法的代码时会返回 true;

因为线程安全的实现,PHP 的多线程开始运行后,无法再通过共享内存空间通信,线程也无法通过线程间通信复用,所以我认为 PHP 的“线程池”并没有什么意义。扩展内自带的Pool 类是一个对多线程分配管理的类,这里也不再多介绍了。


实例代码

下面是一个线程类,用来请求某一接口。接下来根据它写两个多线程的应用实例:

class Request extends Thread {    public $url;    public $response;    public function __construct($url) {        $this->url = $url;    }    public function run() {        $this->response = file_get_contents($this->url);    }}

异步请求

将同步的请求拆分为多个线程异步调用,以提升程序的运行效率。

$chG = new Request("www.google.com");$chB = new Request("www.baidu.com");$chG ->start();$chB ->start();$chG->join();$chB->join(); $gl = $chG->response;$bd = $chB->response;

超时控制

偶然间发现公司网站某一网页上的一块内容时有时无,不知道具体实现,但这给了我使用多线程的灵感:利用线程异步实现快速失败和超时控制。

我们在使用 curl 请求某个地址时,可以通过 CURLOPT_CONNECTTIMEOUT / CURLOPT_TIMEOUT 参数分别设置 curl 的连接超时时间和读取数据超时时间,但总的超时时间不好控制。而且在进行数据库查询时的超时时间无法设置(鸟哥博客:为MySQL设置查询超时)。

这时我们便可以借用多线程来实现此功能:在执行线程类的 start() 方法后,不调用 join() 方法,使线程一直处于异步状态,不阻塞主线程的执行。

此时主线程相当于旗舰,而各子线程相当于巡航舰,旗舰到达某地后不必要一直等待巡航舰也归来,等待一段时间后离开即可,从而避免巡航舰意外时旗舰白白空等。

代码:

$chG = new Request("www.google.com");$chB = new Request("www.baidu.com");$chG->start();$chB->start();$chB->join();// 此处不对chG执行join方法 sleep(1); // sleep一个能接受的超时时间$gl = $chG->response;$bd = $chB->response;$bd->kill();if (!$gl) {    $gl = ""; // 处理异常,或在线程类内给$gl一个默认值}

用php将任何格式视频转为flv的代码

用php将任何格式视频转为flv的代码_php技巧_脚本之家 <?
define(“ROOT_DIR”,dirname(__FILE__));
class EcodeFlv {
var $fromFile; //上传来的文件
var $toFilePath; //保存文件路径
var $toPicPath; //保存图片路径
var $mpeg; //ffmpeg.exe文件的路径
var $mencode; //mencode.exe文件的路径
var $cmdToFile; //转换文件命令
var $cmdToPic; //转换图片命令
var $toFileName; //转换后的文件名
var $mpegComm; //ffmpeg.exe的转换命令
var $mencodeComm; //mencode.exe的命令
var $mpegType;
var $mencodeType;
var $midi; //mdi.exe的路径
var $cmdMidi; //mdi.exe的命令
//初始化类
function EcodeFlv($fromFile,$toFilePath,$toPicPath,$mpeg,$mencode,$midi) {
$this->mpegComm = false;
$this->mencodeComm = false;
$this->fromFile = $fromFile;
$this->toFilePath = $toFilePath;
$this->toPicPath = ROOT_DIR.”/”.$toPicPath;
$this->mpeg = ROOT_DIR.$mpeg;
$this->mencode = ROOT_DIR.$mencode;
$this->midi = ROOT_DIR.$midi;
$this->mpegType=array (
“audio/x-mpeg”=>”.mp3″,
“video/mpeg”=>”.mpeg”,
“video/3gpp”=>”.3gp”,
“video/x-ms-asf”=>”.asf”,
“video/x-msvideo”=>”.avi”
);
$this->mencodeType = array(
“application/vnd.rn-realmedia”=>”.rm”,
“audio/x-pn-realaudio”=>”.rmvb”,
“audio/x-ms-wmv”=>”.wmv”,
);
}

//检查文件类型

function checkType() {
if(function_exists(mime_content_type)){
return false;
}else{
//$contentType = mime_content_type($this->fromFile);
$exe = “D:\server\php\extras\magic”;
$handel = new finfo(FILEINFO_MIME, $exe);
$contentType = $handel->file($this->fromFile);
}
foreach($this->mpegType as $index=>$key){
if($contentType == $index){
$name = md5(date(“Ymd”).tiime());
$this->toFileName = $name;
$this->$mpegComm = true;
return true;
}
}
foreach($this->mencodeType as $index=>$key){
if($contentType == $index){
$name = md5(date(“Ymd”).time());
$this->toFileName = $name;
$this->mencodeComm = true;
return true;
}else{
return false;
}
}
}

//设置文件,图片大小
function setSize($flvSize,$picSize) {
$flvWidth = $flvSize[0];
$flvHeight = $flvSize[1];
$picWidth = $picSize[0];
$picHeight = $picSize[1];
$picName = $this->toPicPath.$this->toFileName.”.jpg”;
$flvName = $this->toFilePath.$this->toFileName.”.flv”;
$toMdi = ROOT_DIR.”/”.$flvName;
$size = $picWidth.”x”.$picHeight;
if($this->mpegComm){
$this->cmdToFile= “$this->mpeg -i $this->fromFile -y -ab 56 -ar 22050 -b 500 -r 15 -s $flvWith*$flvHeight $flvName”;
}
elseif($this->mencodeComm){
$this->cmdToFile = “$this->mencode $this->fromFile -vf scale=$flvWidth:$flvHeight -ffourcc FLV1 -of lavf -ovc lavc -lavcopts vcodec=flv:vbitrate=70:acodec=mp3:abitrate=56:dia=-1 -ofps 25 -srate 22050 -oac mp3lame -o $flvName”;
}
$this->cmdToPic = “$this->mpeg -i $toMdi -y -f image2 -ss 8 -t 0.003 -s $size $picName”;
$this->cmdMidi = “$this->midi $toMdi /k”;
echo $this->cmdToPic;
}

//开始转换
function toEcode() {
set_time_limit(0);
exec($this->cmdToFile,$flvStatus)
exec($this->cmdToPic,$picStatus);
exec($this->cmdMidi,$mStatus);
}

}
?>

JS中Json数据的处理和解析JSON数据的方法详解

原生JS:

把本机json数据或远程返回json数据用eval函数,使之变成DOM对象。
var jsonData = ‘{“name”:”gafish”}’;
var domData = eval(‘(‘+ jsonData +’)’);
alert(domData.name)

jQuery:

把本机json数据或远程返回json数据通过jquery的parseJSON方法,使之变成DOM对象。
var jsonData = ‘{“name”:”gafish”}’;
var domData = jQuery.parseJSON(jsonData);
alert(domData.name)