进入dir目录
cd dir
返回上一级
cd ..
返回上两级
cd ../..
返回根目录
cd /
切换磁盘,例如切换到F盘,不缺分大小写
f:
查看当前目录下的文件和目录
dir
创建名为dir的目录
md dir
只能删除名为dir的空目录
rd dir
删除dir文件,或者删除dir中一级目录下的文件(不包含目录和隐藏文件)
del dir
复制dir文件到另一个dir2文件
copy dir dir2
移动dir文件到另一个dir2文件
move dir dir2
清空cmd窗口内容
cls
打开一个新cmd窗口
start cmd
关闭cmd窗口
exit
查看ip相关的参数
ipconfig
检测IP地址的连通性,丢包率等
ping ip
定时关机,单位秒,例如定时一小时关闭电脑
shutdown -s -t 3600
取消定时关机
shutdown -a
查看电脑最大运行内存,单位:KB
不过这个命令存在很大疑惑,可能只是理论最大的单槽内存,具体还是建议去电脑官网查看。
wmic memphysical get maxcapacity
把*.ts缓存文件合并成一个.ts文件
copy/b ts文件地址\*.ts 复制地址\newfile.ts
ts转mp4格式
ffnpeg -i 文件路径\newfile.ts -acodec copy -vcodec copy -f mp4 生成路径\newfile.mp4
创建指定大小的文件,例如:在当前目录下创建一个名字为test.txt的10GB大小的文件,单位是B
fsutil file createnew test.txt 10737418240
vue单页因微信分享和自动登陆须要,对于URL中存在’#’的地址,处理起来比较坑。
用history模式就不会存在这样的问题。可是换成history模式,就会有个新的问题,就是页面刷新后,页面就没法显示了(404)。
对于这个问题,只需要配置网站Nginx就可以了
server { listen 8888;#默认端口是80,若是端口没被占用能够不用修改 server_name localhost; root E:/vue/my_project/dist;#vue项目的打包后的dist ##############修改配置文件,以上部分应该默认存在,下面两个location是重点############# location / { try_files $uri $uri/ @router;#须要指向下面的@router不然会出现vue的路由在nginx中刷新出现404 index index.html index.htm; } #对应上面的@router,主要缘由是路由的路径资源并非一个真实的路径,因此没法找到具体的文件 #所以须要rewrite到index.html中,而后交给路由在处理请求资源 location @router { rewrite ^.*$ /index.html last; } #.......该文件其余部分于此功能无关,省略 }
把下面代码放在html中就可以直接使用了
<style> .fl { width: 100px; height: 100px; position: fixed; } .fl img{ width: 100%; height: 100%; border-radius: 10%; } </style> <div class="fl" id="fl"> <img src="https://shx1024.top/uploads/admin/author_avatar/20210127/d244575d3237ee43e46bca336b43f7ad.jpg" alt=""> </div> <script> //获取需要浮动的div var fl = document.getElementById('fl'); //计算整个页面的宽高 var chroX = document.documentElement.clientWidth; var chroY = document.documentElement.clientHeight; //获取盒子位置,距离左边和顶部的距离 var offsetLeft = fl.offsetLeft; var offsetTop = fl.offsetTop; //setInterval停止标识 var timer = 0; //每次x轴和y轴的移动距离 var x = 1; var y = 1; //浏览器放大或缩小时重新获取页面宽高 window.onresize = function () { chroX = document.documentElement.clientWidth;//yemian整个的高宽 chroY = document.documentElement.clientHeight; } //浮窗移动的方法 function move() { offsetLeft += x; offsetTop += y; fl.style.left = offsetLeft + 'px'; fl.style.top = offsetTop + 'px'; } //浏览器加载完毕自动调用 window.onload = function () { timer = setInterval(function () { move(); if (offsetTop + 100 > chroY || offsetTop < 0) { y = -y; } if (offsetLeft + 100 > chroX || offsetLeft < 0) { x = -x; } }, 10) } //鼠标悬停在浮窗时停止移动 fl.onmouseenter = function () { clearInterval(timer) } //鼠标离开浮窗时继续移动 fl.onmouseleave = function () { window.onload(); } </script>
1、环境确认,仅支持 Linux(2.3.32 以上内核)、FreeBSD、MacOS 三种操作系统,低版本 Linux 系统(如 CentOS 6)可以使用 RedHat 提供的 devtools 编译,参考文档, 在 Windows 平台,可使用 WSL(Windows Subsystem for Linux) 或 CygWin。
2、系统软件:
php-7.2 或更高版本 gcc-4.8 或更高版本 make autoconf
3、下载swoole源码(三选一)
https://github.com/swoole/swoole-src/releases https://pecl.php.net/package/swoole https://gitee.com/swoole/swoole/tags
4、下载源代码包后,使用root权限的终端进入源码目录,执行下面的命令进行编译和安装(当前教程安装的是4.8.0版本)
①进入下载的安装目录中:
cd swoole
②执行下面命令进入安装模块:
phpize && \
③设置configure中的安装目录
./configure --with-php-config=/www/server/php/72/bin/php-config
④最后通过以下命令执行安装:
make && make install
⑤执行完成后看看安装目录下有无swoole.so文件,php.ini中有无extension=swoole.so
#我成功安装后,swoole.so所在目录: /www/server/php/72/lib/php/extensions/no-debug-non-zts-20170718/swoole.so
注:如果不知道第③步中的安装目录,则可以执行下面命令进行全局查找
find / -name php-config
PHP代码部分
//创建WebSocket Server对象,监听0.0.0.0:9502端口 $ws = new \Swoole\WebSocket\Server('0.0.0.0', 9502); //监听WebSocket连接打开事件 $ws->on('Open', function ($ws, $request) { $socket_id = $request->fd; $nowtime = date("Y-m-d H:i:s"); echo "[{$nowtime}] {$socket_id}连接成功\n"; $ws->push($socket_id, "swoole连接成功!\n"); }); //监听WebSocket消息事件 $ws->on('Message', function ($ws, $frame) { $socket_id = $frame->fd; $data = $frame->data; $nowtime = date("Y-m-d H:i:s"); echo "[{$nowtime}] 收到的客户端信息: {$data}\n"; $ws->push($socket_id, "收到的客户端信息: {$frame->data}"); }); //监听WebSocket连接关闭事件 $ws->on('Close', function ($ws, $fd) { $nowtime = date("Y-m-d H:i:s"); echo "[{$nowtime}] socket_id为{$fd}的用户已关闭连接\n"; }); $ws->start();
运行swoole
php swoole.php
客户端JS代码部分:
var wsServer = 'ws://服务器IP地址:9502'; var websocket = new WebSocket(wsServer); websocket.onopen = function (evt) { console.log("swoole连接成功!"); websocket.send('测试数据') }; websocket.onclose = function (evt) { console.log("swoole连接断开!"); }; websocket.onmessage = function (evt) { console.log('服务器返回的数据为: ' + evt.data); }; websocket.onerror = function (evt, e) { console.log('发生错误: ' + evt.data); };
注(踩的坑):
①检查防火墙9502端口是否开放
②以上教程在有ssl证书的情况下会连接失败
想在ssl证书下运行swoole,需要到swoole目录下重新安装程序:
①进入安装目录,执行下面命令进入安装模块:
执行下面命令进入安装模块:
phpize && \
②设置configure中的安装目录,并带有ssl安装,找不到目录参考上面find命令
./configure --enable-openssl --with-php-config=/www/server/php/72/bin/php-config
③清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件
make clean
④最后通过以下命令执行安装
make && make install
⑤查看结果是否包含openssl
php --ri swoole
看结果中是否存在下面这行,时间可能不一致,但前半部分相同
openssl => OpenSSL 1.0.2k-fips 26 Jan 2017
①客户端修改访问地址
var wsServer = 'ws://服务器IP地址:9502'; //上面改为下面,其他代码不动即可 var wsServer = 'wss://域名/自定义模块名(不要和代码中的功能模块名重复)'; //例如 var wsServer = 'wss://shx1024.top/websocket/';
②Nginx配置代理(其实是将指向https的服务重定向到http):
#在代理服务器上的nginx配置文件中的server中增加如下配置项 location /websocket/ { proxy_pass http://服务器IP地址:9502; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
③重新运行swoole
php swoole.php
①客户端修改访问地址
var wsServer = 'ws://服务器IP地址:9502'; //上面改为下面,其他代码不动即可 var wsServer = 'wss://服务器IP地址:9502';
②服务器端为WebSocket服务器增加ssl证书,这样就可以直接通过wss://来请求服务器了
//使用SSL必须在编译swoole时加入--enable-openssl选项 $server = new Swoole\WebSocket\Server("0.0.0.0", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); $server->set( [ 'ssl_cert_file' => '证书cert地址', 'ssl_key_file' => '证书key地址', ] ); //注:宝塔SSL证书所在目录:/www/server/panel/vhost/ssl/你的网站域名
③重新运行swoole
php swoole.php
1、all
如果数组所有元素满足函数条件,则返回true。调用时,如果省略第二个参数,则默认传递布尔值。
const all = (arr, fn = Boolean) => arr.every(fn); all([4, 2, 3], x => x > 1); // trueall([1, 2, 3]); // true
2、allEqual
判断数组中的元素是否都相等
const allEqual = arr => arr.every(val => val === arr[0]); allEqual([1, 2, 3, 4, 5, 6]); // falseallEqual([1, 1, 1, 1]); // true
3、approximatelyEqual
此代码示例检查两个数字是否近似相等,差异值可以通过传参的形式进行设置
const approximatelyEqual = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) < epsilon; approximatelyEqual(Math.PI / 2.0, 1.5708); // true
4、arrayToCSV
此段代码将没有逗号或双引号的元素转换成带有逗号分隔符的字符串即CSV格式识别的形式。
const arrayToCSV = (arr, delimiter = ',') => arr.map(v => v.map(x => `"${x}"`).join(delimiter)).join('\n'); arrayToCSV([['a', 'b'], ['c', 'd']]); // '"a","b"\n"c","d"' arrayToCSV([['a', 'b'], ['c', 'd']], ';'); // '"a";"b"\n"c";"d"'
5、arrayToHtmlList
此段代码将数组元素转换成标记,并将此元素添加至给定的ID元素标记内。
const arrayToHtmlList = (arr, listID) => (el => ( (el = document.querySelector('#' + listID)), (el.innerHTML += arr.map(item => `${item}`).join('')) ))(); arrayToHtmlList(['item 1', 'item 2'], 'myListID');
6、attempt
此段代码执行一个函数,将剩余的参数传回函数当参数,返回相应的结果,并能捕获异常。
const attempt = (fn, ...args) => { try { return fn(...args); } catch (e) { return e instanceof Error ? e : new Error(e); } }; var elements = attempt(function(selector) { return document.querySelectorAll(selector); }, '>_>'); if (elements instanceof Error) elements = []; // elements = []
7、average
此段代码返回两个或多个数的平均数。
const average = (...nums) => nums.reduce((acc, val) => acc + val, 0) / nums.length; average(...[1, 2, 3]); // 2 average(1, 2, 3); // 2
8、averageBy
一个 map()函数和 reduce()函数结合的例子,此函数先通过 map() 函数将对象转换成数组,然后在调用reduce()函数进行累加,然后根据数组长度返回平均值。
const averageBy = (arr, fn) =>arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0) / arr.length; averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 5 averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5
9、bifurcate
此函数包含两个参数,类型都为数组,依据第二个参数的真假条件,将一个参数的数组进行分组,条件为真的放入第一个数组,其它的放入第二个数组。这里运用了Array.prototype.reduce() 和 Array.prototype.push() 相结合的形式。
const bifurcate = (arr, filter) =>arr.reduce((acc, val, i) =>(acc[filter[i] ? 0 : 1].push(val), acc), [[], []]); bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]);// [ ['beep', 'boop', 'bar'], ['foo'] ]
10、bifurcateBy
此段代码将数组按照指定的函数逻辑进行分组,满足函数条件的逻辑为真,放入第一个数组中,其它不满足的放入第二个数组 。
这里运用了Array.prototype.reduce() 和 Array.prototype.push() 相结合的形式,基于函数过滤逻辑,通过 Array.prototype.push() 函数将其添加到数组中。
const bifurcateBy = (arr, fn) =>arr.reduce((acc, val, i) => (acc[fn(val, i) ? 0 : 1].push(val), acc), [[], []]); bifurcateBy(['beep', 'boop', 'foo', 'bar'], x => x[0] === 'b');// [ ['beep', 'boop', 'bar'], ['foo'] ]
11、bottomVisible
用于检测页面是否滚动到页面底部。
const bottomVisible = () =>document.documentElement.clientHeight + window.scrollY >= (document.documentElement.scrollHeight || document.documentElement.clientHeight); bottomVisible(); // true
12、byteSize
此代码返回字符串的字节长度。这里用到了Blob对象,Blob(Binary Large Object)对象代表了一段二进制数据,提供了一系列操作接口。其他操作二进制数据的API(比如File对象),都是建立在Blob对象基础上的,继承了它的属性和方法。生成Blob对象有两种方法:一种是使用Blob构造函数,另一种是对现有的Blob对象使用slice方法切出一部分。
const byteSize = str => new Blob([str]).size; byteSize('?'); // 4 byteSize('Hello World'); // 11
13、capitalize
将字符串的首字母转成大写,这里主要运用到了ES6的展开语法在数组中的运用。
const capitalize = ([first, ...rest]) => first.toUpperCase() + rest.join(''); capitalize('fooBar'); // 'FooBar' capitalize('fooBar', true); // 'FooBar'
14、capitalizeEveryWord
将一个句子中每个单词首字母转换成大写字母,这里中要运用了正则表达式进行替换。
const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); capitalizeEveryWord('hello world!'); // 'Hello World!'
15、castArray
此段代码将非数值的值转换成数组对象。
const castArray = val => (Array.isArray(val) ? val : [val]); castArray('foo'); // ['foo'] castArray([1]); // [1]
16、compact
将数组中移除值为 false 的内容。
const compact = arr => arr.filter(Boolean); compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]); // [ 1, 2, 3, 'a', 's', 34 ]
17、countOccurrences
统计数组中某个值出现的次数。
const countOccurrences = (arr, val) =>arr.reduce((a, v) => (v === val ? a + 1 : a), 0); countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3
18、Create Directory
此代码段使用 existSync() 检查目录是否存在,然后使用 mkdirSync() 创建目录(如果不存在)。
const fs = require('fs'); const createDirIfNotExists = dir =>(!fs.existsSync(dir) ? fs.mkdirSync(dir) : undefined); createDirIfNotExists('test'); // creates the directory 'test', if it doesn't exist
19、currentURL
返回当前访问的 URL 地址。
const currentURL = () => window.location.href; currentURL(); // 'https://shx1024.top/'
20、dayOfYear
返回当前是今年的第几天
const dayOfYear = date =>Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24); dayOfYear(new Date()); // 281
21、decapitalize
将字符串的首字母转换成小写字母。
const decapitalize = ([first, ...rest]) =>first.toLowerCase() + rest.join('') decapitalize('FooBar'); // 'fooBar'
22、deepFlatten
通过递归的形式,将多维数组展平成一维数组。
const deepFlatten = arr =>[].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v))); deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]
23、default
去重对象的属性,如果对象中含有重复的属性,以前面的为准。
const defaults = (obj, ...defs) =>Object.assign({}, obj, ...defs.reverse(), obj); defaults({ a: 1 }, { b: 2 }, { b: 6 }, { a: 3 }); // { a: 1, b: 2 }
24、defer
延迟函数的调用,即异步调用函数。
const defer = (fn, ...args) => setTimeout(fn, 1, ...args); defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a'
25、degreesToRads
此段代码将标准的度数,转换成弧度。
const degreesToRads = deg => (deg * Math.PI) / 180.0; degreesToRads(90.0); // ~1.5708
26、difference
此段代码查找两个给定数组的差异,查找出前者数组在后者数组中不存在元素。
const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; difference([1, 2, 3], [1, 2, 4]); // [3]
27、differenceBy
通过给定的函数来处理需要对比差异的数组,查找出前者数组在后者数组中不存在元素。
const differenceBy = (a, b, fn) => { const s = new Set(b.map(fn)); return a.filter(x => !s.has(fn(x))); }; differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [1.2] differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], v => v.x); // [ { x: 2 } ]
28、differenceWith
此段代码按照给定函数逻辑筛选需要对比差异的数组,查找出前者数组在后者数组中不存在元素。
const differenceWith = (arr, val, comp) =>arr.filter(a => val.findIndex(b => comp(a, b)) === -1); differenceWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0], (a, b) => Math.round(a) === Math.round(b));// [1, 1.2]
29、digitize
将输入的数字拆分成单个数字组成的数组。
const digitize = n => [...`${n}`].map(i => parseInt(i)); digitize(431); // [4, 3, 1]
30、distance
计算两点之间的距离
const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); distance(1, 1, 2, 3); // 2.23606797749979
31、drop
此段代码将给定的数组从左边开始删除 n 个元素
const drop = (arr, n = 1) => arr.slice(n); drop([1, 2, 3]); // [2,3] drop([1, 2, 3], 2); // [3] drop([1, 2, 3], 42); // []
32、dropRight
此段代码将给定的数组从右边开始删除 n 个元素
const dropRight = (arr, n = 1) => arr.slice(0, -n); dropRight([1, 2, 3]); // [1,2] dropRight([1, 2, 3], 2); // [1] dropRight([1, 2, 3], 42); // []
33、dropRightWhile
此段代码将给定的数组按照给定的函数条件从右开始删除,直到当前元素满足函数条件为True时,停止删除,并返回数组剩余元素。
const dropRightWhile = (arr, func) => { while (arr.length > 0 && !func(arr[arr.length - 1])) arr = arr.slice(0, -1); return arr; }; dropRightWhile([1, 2, 3, 4], n => n < 3); // [1, 2]
34、dropWhile
按照给的的函数条件筛选数组,不满足函数条件的将从数组中移除。
const dropWhile = (arr, func) => { while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); return arr; }; dropWhile([1, 2, 3, 4], n => n >= 3); // [3,4]
35、elementContains
接收两个DOM元素对象参数,判断后者是否是前者的子元素。
const elementContains = (parent, child) => parent !== child && parent.contains(child); elementContains(document.querySelector('head'), document.querySelector('title')); // true elementContains(document.querySelector('body'), document.querySelector('body')); // false
36、filterNonUnique
移除数组中重复的元素
const filterNonUnique = arr => [ …new Set(arr)]; filterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1, 2, 3, 4, 5]
37、findKey
按照给定的函数条件,查找第一个满足条件对象的键值。
const findKey = (obj, fn) => Object.keys(obj).find(key => fn(obj[key], key, obj)); findKey( { barney: { age: 36, active: true }, fred: { age: 40, active: false }, pebbles: { age: 1, active: true } }, o => o['active'] ); // 'barney'
38、findLast
按照给定的函数条件筛选数组,将最后一个满足条件的元素进行删除。
const findLast = (arr, fn) => arr.filter(fn).pop(); findLast([1, 2, 3, 4], n => n % 2 === 1); // 3
39、flatten
按照指定数组的深度,将嵌套数组进行展平。
const flatten = (arr, depth = 1) =>arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), []); flatten([1, [2], 3, 4]); // [1, 2, 3, 4] flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
40、forEachRight
按照给定的函数条件,从数组的右边往左依次进行执行。
const forEachRight = (arr, callback) =>arr.slice(0).reverse().forEach(callback); forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'
41、forOwn
此段代码按照给定的函数条件,支持三个参数作为输入(值、键、对象本身),进行迭代对象。
const forOwn = (obj, fn) =>Object.keys(obj).forEach(key => fn(obj[key], key, obj)); forOwn({ foo: 'bar', a: 1 }, v => console.log(v)); // 'bar', 1
42、functionName
此段代码输出函数的名称。
const functionName = fn => (console.debug(fn.name), fn); functionName(Math.max); // max (logged in debug channel of console)
43、getColonTimeFromDate
此段代码从Date对象里获取当前时间。
const getColonTimeFromDate = date => date.toTimeString().slice(0, 8); getColonTimeFromDate(new Date()); // "08:38:00"
44、getDaysDiffBetweenDates
此段代码返回两个日期之间相差多少天。
const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>(dateFinal - dateInitial) / (1000 * 3600 * 24); getDaysDiffBetweenDates(new Date('2019-01-13'), new Date('2019-01-15')); // 2
45、getStyle
此代码返回DOM元素节点对应的属性值。
const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName]; getStyle(document.querySelector('p'), 'font-size'); // '16px'
46、getType
此段代码的主要功能就是返回数据的类型。
const getType = v =>v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); getType(new Set([1, 2, 3])); // 'set'
47、hasClass
此段代码返回DOM元素是否包含指定的Class样式。
const hasClass = (el, className) => el.classList.contains(className); hasClass(document.querySelector('p.special'), 'special'); // true
48、head
此段代码输出数组的第一个元素。
const head = arr => arr[0]; head([1, 2, 3]); // 1
49、hide
此段代码隐藏指定的DOM元素。
const hide = (...el) => [...el].forEach(e => (e.style.display = 'none')); hide(document.querySelectorAll('img')); // Hides all elements on the page
50、httpsRedirect
此段代码的功能就是将http网址重定向https网址。
const httpsRedirect = () => { if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); }; httpsRedirect(); // If you are on http://shx1024.top, you are redirected to https://shx1024.top
51、indexOfAll
此代码可以返回数组中某个值对应的所有索引值,如果不包含该值,则返回一个空数组。
const indexOfAll = (arr, val) =>arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []); indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3] indexOfAll([1, 2, 3], 4); // []
52、initial
此段代码返回数组中除最后一个元素的所有元素。
const initial = arr => arr.slice(0, -1); initial([1, 2, 3]); // [1,2] initial([1, 2, 3, 4]); // [1,2,3]
53、insertAfter
此段代码的功能主要是在给定的DOM节点后插入新的节点内容
const insertAfter = (el, htmlString) =>el.insertAdjacentHTML('afterend', htmlString); insertAfter(document.getElementById('myId'), 'after'); //...after
54、insertBefore
此段代码的功能主要是在给定的DOM节点前插入新的节点内容
const insertBefore = (el, htmlString) =>el.insertAdjacentHTML('beforebegin', htmlString); insertBefore(document.getElementById('myId'), 'before'); //before...
55、intersection
此段代码返回两个数组元素之间的交集。
const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); }; intersection([1, 2, 3], [4, 3, 2]); // [2, 3]
56、intersectionBy
按照给定的函数处理需要对比的数组元素,然后根据处理后的数组,找出交集,最后从第一个数组中将对应的元素输出。
const intersectionBy = (a, b, fn) => { const s = new Set(b.map(fn)); return a.filter(x => s.has(fn(x))); }; intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [2.1]
57、intersectionBy
按照给定的函数对比两个数组的差异,然后找出交集,最后从第一个数组中将对应的元素输出。
const intersectionWith = (a, b, comp) =>a.filter(x => b.findIndex(y => comp(x, y)) !== -1); intersectionWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0, 3.9], (a, b) => Math.round(a) === Math.round(b)); // [1.5, 3, 0]
58、is
此段代码用于判断数据是否为指定的数据类型,如果是则返回true。
const is = (type, val) => ![, null].includes(val) && val.constructor === type; is(Array, [1]); // true is(ArrayBuffer, new ArrayBuffer()); // true is(Map, new Map()); // true is(RegExp, /./g); // true is(Set, new Set()); // true is(WeakMap, new WeakMap()); // true is(WeakSet, new WeakSet()); // true is(String, ''); // true is(String, new String('')); // true is(Number, 1); // true is(Number, new Number(1)); // true is(Boolean, true); // true is(Boolean, new Boolean(true)); // true
59、isAfterDate
接收两个日期类型的参数,判断前者的日期是否晚于后者的日期。
const isAfterDate = (dateA, dateB) => dateA > dateB; isAfterDate(new Date(2010, 10, 21), new Date(2010, 10, 20)); // true
60、isAnagram
用于检测两个单词是否相似。
const isAnagram = (str1, str2) => { const normalize = str =>str.toLowerCase().replace(/[^a-z0-9]/gi, '').split('') .sort().join(''); return normalize(str1) === normalize(str2); }; isAnagram('iceman', 'cinema'); // true
61、isArrayLike
此段代码用于检测对象是否为类数组对象,是否可迭代。
const isArrayLike = obj => obj != null && typeof obj[Symbol.iterator] === 'function'; isArrayLike(document.querySelectorAll('.className')); // true isArrayLike('abc'); // true isArrayLike(null); // false
62、isBeforeDate
接收两个日期类型的参数,判断前者的日期是否早于后者的日期。
const isBeforeDate = (dateA, dateB) => dateA < dateB; isBeforeDate(new Date(2010, 10, 20), new Date(2010, 10, 21)); // true
63、isBoolean
此段代码用于检查参数是否为布尔类型。
const isBoolean = val => typeof val === 'boolean'; isBoolean(null); // false isBoolean(false); // true
64、getColonTimeFromDate
用于判断程序运行环境是否在浏览器,这有助于避免在node环境运行前端模块时出错。
const isBrowser = () => ![typeof window, typeof document].includes('undefined'); isBrowser(); // true (browser) isBrowser(); // false (Node)
65、isBrowserTabFocused
用于判断当前页面是否处于活动状态(显示状态)。
const isBrowserTabFocused = () => !document.hidden; isBrowserTabFocused(); // true
66、isLowerCase
用于判断当前字符串是否都为小写。
const isLowerCase = str => str === str.toLowerCase(); isLowerCase('abc'); // true isLowerCase('a3@$'); // true isLowerCase('Ab4'); // false
67、isNil
用于判断当前变量的值是否为 null 或 undefined 类型。
const isNil = val => val === undefined || val === null; isNil(null); // true isNil(undefined); // true
68、isNull
用于判断当前变量的值是否为 null 类型。
const isNull = val => val === null; isNull(null); // true
69、isNumber
用于检查当前的值是否为数字类型。
function isNumber(n) { return !isNaN(parseFloat(n)) && isFinite(n); } isNumber('1'); // false isNumber(1); // true
70、isObject
用于判断参数的值是否是对象,这里运用了Object 构造函数创建一个对象包装器,如果是对象类型,将会原值返回。
const isObject = obj => obj === Object(obj); isObject([1, 2, 3, 4]); // true isObject([]); // true isObject(['Hello!']); // true isObject({ a: 1 }); // true isObject({}); // true isObject(true); // false
71、isObjectLike
用于检查参数的值是否为null以及类型是否为对象。
const isObjectLike = val => val !== null && typeof val === 'object'; isObjectLike({}); // true isObjectLike([1, 2, 3]); // true isObjectLike(x => x); // false isObjectLike(null); // false
72、isPlainObject
此代码段检查参数的值是否是由Object构造函数创建的对象。
const isPlainObject = val => !!val && typeof val === 'object' && val.constructor === Object; isPlainObject({ a: 1 }); // true isPlainObject(new Map()); // false
73、isPromiseLike
用于检查当前的对象是否类似Promise函数。
const isPromiseLike = obj =>obj !== null && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; isPromiseLike({ then: function() { return ''; } }); // true isPromiseLike(null); // false isPromiseLike({}); // false
74、isSameDate
用于判断给定的两个日期是否是同一天。
const isSameDate = (dateA, dateB) =>dateA.toISOString() === dateB.toISOString(); isSameDate(new Date(2010, 10, 20), new Date(2010, 10, 20)); // true
75、isString
用于检查当前的值是否为字符串类型。
const isString = val => typeof val === 'string'; isString('10'); // true
76、isSymbol
用于判断参数的值是否是 Symbol 类型。
const isSymbol = val => typeof val === 'symbol'; isSymbol(Symbol('x')); // true
77、isUndefined
用于判断参数的类型是否是 Undefined 类型。
const isUndefined = val => val === undefined; isUndefined(undefined); // true
78、isUpperCase
用于判断当前字符串的字母是否都为大写。
const isUpperCase = str => str === str.toUpperCase(); isUpperCase('ABC'); // trueisLowerCase('A3@$'); // trueisLowerCase('aB4'); // false
79、isValidJSON
用于判断给定的字符串是否是 JSON 字符串。
const isValidJSON = str => { try { JSON.parse(str); return true; } catch (e) { return false; } }; isValidJSON('{"name":"Adam","age":20}'); // true isValidJSON('{"name":"Adam",age:"20"}'); // false isValidJSON(null); // true
80、last
此函数功能返回数组的最后一个元素。
const last = arr => arr[arr.length - 1]; last([1, 2, 3]); // 3
81、matches
此函数功能用于比较两个对象,以确定第一个对象是否包含与第二个对象相同的属性与值。
onst matches = (obj, source) =>Object.keys(source).every(key => obj.hasOwnProperty(key) && obj[key] === source[key]); matches({ age: 25, hair: 'long', beard: true }, { hair: 'long', beard: true }); // true matches({ hair: 'long', beard: true }, { age: 25, hair: 'long', beard: true }); // false
82、maxDate
此代码段查找日期数组中最大的日期进行输出。
const maxDate = (...dates) => new Date(Math.max.apply(null, ...dates)); const array = [ new Date(2017, 4, 13), new Date(2018, 2, 12), new Date(2016, 0, 10), new Date(2016, 0, 9) ]; maxDate(array); // 2018-03-11T22:00:00.000Z
83、maxN
此段代码输出数组中前 n 位最大的数。
const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n); maxN([1, 2, 3]); // [3] maxN([1, 2, 3], 2); // [3,2]
84、minDate
此代码段查找日期数组中最早的日期进行输出。
const minDate = (...dates) => new Date(Math.min.apply(null, ...dates)); const array = [ new Date(2017, 4, 13), new Date(2018, 2, 12), new Date(2016, 0, 10), new Date(2016, 0, 9) ]; minDate(array); // 2016-01-08T22:00:00.000Z
1、首先查看当前php命令运行的是哪个版本
ls /usr/bin/php -al
2、查看当前php运行目录
find / -name php
3、删除当前运行的目录
rm -rf /usr/bin/php
4.用ln -s 命令重新建立连接
ln -s /www/server/php/70/bin/php /usr/bin/php
前提:此命令在windows平台上不可用,且最好是在cli(命令行)下运行(ps:宝塔默认禁用pcntl_fork()函数)。
需要用到pcntl_fork()函数,此函数创建一个子进程,父进程和子进程都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程号,而子进程得到的是0。
const NEWLINE = "\n\n"; if (strtolower(php_sapi_name()) != 'cli') { die("请在cli模式下运行"); } echo "当前进程(执行fork前):" . getmypid() . NEWLINE; //fork出子进程 $pid = pcntl_fork(); //fork后父进程会走自己的逻辑,子进程从处开始走自己的逻辑,堆栈信息会完全复制给子进程内存空间,父子进程相互独立 if ($pid == -1) { // 创建错误,返回-1 die('进程fork失败'); } else if ($pid) { // $pid > 0, 如果fork成功,在子进程中pid为0,而父进程中pid则大于0。 // 父进程逻辑 $time = microtime(true); $thispid=getmypid(); echo "{$thispid}-{$pid}-我是父进程:{$time}".NEWLINE; } else { // $pid = 0 // 子进程逻辑 $time = microtime(true); $thispid=getmypid(); echo "{$thispid}-{$pid}-我是子进程-{$pid}:{$time}".NEWLINE; }
补充:getmypid()获取当前进程id。
一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。
Apache总是试图保持一些备用的 (spare)或是空闲的子进程用于迎接即将到来的请求。
这样客户端就无需在得到服务前等候子进程的产生。
最明显的例子就是在CGI模式下,如果修改了php.ini的配置文件,不用重启web服务便可生效(每次都会加载php.ini的配置,这也是导致性能能地下的一个原因)。而模块模式下需要重启web服务。
以mod_php模式运行PHP,意味着PHP是作为Apache的一个模块来启动的,因此只有在Apache启动的时候会读取php.ini配置文件并加载扩展模块,在Apache运行期间是不会再去读取和加载扩展模块的。
当一个服务web-service(nginx)分配过来请求的时候,通过匹配后缀是动态的php的请求。CGI就会去读取php.ini的基本配置信息,初始化环境,创建进程,返回数据,退出进程。每一次请求都是循环往复,所以有些繁琐,这是后面为什么会诞生fastcgi的原因。
这种形式是CGI的加强版本,CGI是单进程,FastCGI多线程的运行方式,程序执行完成之后就会销毁,所以每次都需要加载配置和环境变量fork-and-execute(创建-执行)。
而FastCGI则不同,FastCGI 像是一个常驻 (long-live) 型的 CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去 fork 一次。
FastCGI进程管理器自身初始化,启动多个CGI解释器进程 (在任务管理器中可见多个php-cgi.exe)并等待来自Web Server的连接。
命令行运行。
array_key_exists() 会检查键值的存在. 这个函数会返回TRUE,只要键值存在,即使值为NULL.
$data = array("one" => "1", "two" => "", "three" => null); var_dump(array_key_exists("one", $data));// true var_dump(array_key_exists("two", $data));// true var_dump(array_key_exists("three", $data));// true
和arrry_key_exitst()不同,isset()会同时检查键和值,只有当健存在,对应的变量不为NUll的时候才会返回TURE。
$data = array("one" => "1", "two" => "", "three" => null); var_dump(isset($data['one']));// true var_dump(isset($data['two']));// true var_dump(isset($data['three']));// false
S:Sever服务器
C:Client
B:Browser
具有分布性的特点(前后端分离),可以随时随地进行查询、浏览等业务处理。
业务扩展简单,通过增加网页即可增加服务器功能。
维护简单方便,只需要改变网页,即可实现所有用户的同步更新。
不需要安装客户端,可以直接运行在web浏览器中。
逻辑结构比C/S多一层,处理速度较慢。
交互能力较差,不能够在子程序间自由切换。
安全性较差,许多信息容易暴露在浏览器中。
应用服务器运行数据负荷较轻。
具有较强的事务处理能力,能实现复杂的业务流程。
由于客户端与服务器直接相连,中间没有环节,因此响应速度更快。
数据的储存管理功能较为透明,这是相当于前台用户来说的,他们无需过问(也无法干涉)背后的逻辑过程。
客户端需要安装专用的客户端软件。
对客户端的操作系统一般也会有限制。
兼容性差,对于不同的开发工具有较大的局限性。
开发成本相对较高。需要一定专业水准的技术人员才能完成。