辰迅云帮助中心

帮助中心

这篇文章主要介绍Yii2.0 Basic代码中路由链接被转义怎么处理,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!按照惯例,说下运行环境和各版本编号OS:Windows10Apache:2.4MySQL:5.7.15PHP:7.0.11问题描述:按照官网的提示,下载了basic版本的代码,配置了虚拟域名,打开浏览器可以访问了(具体过程略)。但是,在点击链接地址时会发现,链接地址被转义了,“/”变成了“%2F”。查找代码,一步一步找。找到最后yii-v2.0.9-basic\vendor\yiisoft\yii2\web\UrlManager.php 第371行,发现url链接被urlencode转义了,这里我把它拿掉了。再访问就OK了。最后贴上代码查找路径:yii-v2.0.9-basic\views\layouts\main.phpyii-v2.0.9-basic\vendor\yiisoft\yii2-bootstrap\Nav.php (200行 Html::a()方法)yii-v2.0.9-basic\vendor\yiisoft\yii2-bootstrap\Html.phpyii-v2.0.9-basic\vendor\yiisoft\yii2-bootstrap\BaseHtml.phpyii-v2.0.9-basic\vendor\yiisoft\yii2\helpers\Html.phpyii-v2.0.9-basic\vendor\yiisoft\yii2\helpers\BaseHtml.phpyii-v2.0.9-basic\vendor\yiisoft\yii2\helpers\Url.phpyii-v2.0.9-basic\vendor\yiisoft\yii2\helpers\BaseUrl.php(102行 static::getUrlManager()->createUrl)yii-v2.0.9-basic\vendor\yiisoft\yii2\web\UrlManager.php(371行 urlencode方法)以上是“Yii2.0 Basic代码中路由链接被转义怎么处理”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注辰迅云资讯频道!...

这篇文章将为大家详细讲解有关YII2框架中如何通过Composer安装扩展插件,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。例如:通过Composer安装插件yii2-detail-view。Git推荐安装Git,Composer安装插件时候会用到Git Clone如果你没有安装过Git,CMD执行命令时会提示你git不是有效的命令。然后去找硬盘下载地址。实际上不安装git也没影响。Windows下安装完Git,配置下环境变量,把;D:\Program Files\Git\bin加入Path环境变量中。安装方法yii2-detail-view官方说明:Installation  The preferred way to install this extension is through composer. Either run: $ php composer.phar require kartik-v/yii2-detail-view "*"or add:"kartik-v/yii2-detail-view": "*"to the require section of your composer.json file.这是相对于Linux环境下安装的方法,Windows下使用ComposerCMD下执行命令:composer require kartik-v/yii2-detail-view "*"安装完毕,我们会看到安装过程中,安装了5个其他的插件,这些都是和yii2-detail-view有依赖关系的插件,这就是Composer工具的好用之处,自动分析依赖关系,帮助我们完美安装。在webroot/appname/vendor目录下看见"kartik-v"目录。看到路径下存放着6个目录。说明安装成功。关于“YII2框架中如何通过Composer安装扩展插件”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。...

CSS布局中BFC的详细介绍

2021/9/6 21:02:26

本篇内容介绍了“CSS布局中BFC的详细介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录前言目录什么是 BFCBFC 是布局中的迷你布局创建一个 BFC 的常用方式创建 BFC 的新方式什么是 BFC一个简单的浮动的示例就能明白 BFC 的行为在下面的示例中我们创建一个 box 元素该元素包裹一段文字和一个浮动的图片。 如果文字内容多的话文字将环绕着整个浮动图片box 的边框会把他们整个包裹起来。123456<div class="outer">      <div class="float">I am a floated element.</div>       I am text inside the outer box.</div>1234567891011121314151617181920.outer {      border: 5px dotted rgb(214,129,137);      border-radius: 5px;      width: 450px;      padding: 10px;      margin-bottom: 40px;}.float {      padding: 10px;      border: 5px solid rgba(214,129,137,.4);      border-radius: 5px;      background-color: rgba(233,78,119,.4);      color: #fff;      float: left;        width: 200px;      margin: 0 20px 0 0;}文字环绕着浮动元素但如果把一些文字删除就没有足够的文字去环绕图片浮动元素了同时由于浮动元素脱离文档流box 元素的边框高度就会随文字的减少而降低。没有足够的文字box 元素边框的高度就会低于浮动元素的高度之所以会发生这种情况是由于当我们浮动一个元素后box 元素仍然保持原来的宽度是文字所占的空间缩短了以给浮动元素腾出位置这就是为什么背景和边框能够看起来包裹住了浮动元素。我们通常会使用两种不同的方式来解决这个问题一种是使用 clear hack就是在 文字和图片的下方插入一个 div 并将它的 CSS clear 属性设值为 both。另外一种方法是使用 overflow 属性 把它设值成非默认值 visible的值。12345.outer {      overflow: auto;}使用 overflow: auto 后 box 就能包裹浮动元素了overflow 之所以能够有效是因为当它的是是非 visible 时会创建一个 BFC而 BFC 的功能之一就是包裹浮动元素。BFC 是布局中的迷你布局你可以把 BFC 当做你页面中的一块小布局当一个元素被创建成 BFC 后它其中的所有元素都会被它包裹。正如我们所见当 box 元素变成 BFC 后它其中的浮动元素就再也没能突破它的底部。除此之外BFC 还有一些有用的功能。BFC 可以阻挡外边距叠加margins collapsing理解外边距叠加是另外一个被低估的 CSS 技巧。在接下来的示例里我创建了一个背景灰色的 div这个 div 含有两个段落div 元素的 margin-bottom 为 40px同时每个段落都有 20px 的 margin-top 与 margin-bottom。12345678910111213.outer {       background-color: #ccc;      margin: 0 0 40px 0;}p {      padding: 0;      margin: 20px 0 20px 0;      background-color: rgb(233,78,119);      color: #fff;}由于 p 元素的边缘与 outer 元素的边缘之间没有任何东西所以 outer 与 p 的 margin 会叠加p 会与 outer 的顶部与底部齐平p 对外的 margin 似乎与 outer 的 margin 合并了使我们无法在段落的上下看到 outer 的灰色背景。由于 margin collapse外边距叠加我们看到 outer 内部上下没有灰色背景如果我们把 outer 元素变成 BFC它就可以包裹住 p 以及 p 的 margin外边距不会发生叠加outer 元素内部就会出现由 p 元素的 margin 顶出来的上下灰色背景。1234567.outer {       background-color: #ccc;      margin: 0 0 40px 0;      overflow: auto;}建立 BFC 后外边距不再叠加一旦 BFC 建立它就会阻止它内部的元素逃离突破它。一个 BFC 会停止去环绕浮动元素你可能很熟悉 BFC 的这个特性我们在有浮动元素的列类型布局中常用到。如果一个元素创建了 BFC它就不会去环绕或者说包装任何浮动元素。看下面这个示例123456<div class="outer">      <div class="float">I am a floated element.</div>      <div class="text">I am text</div></div>class 名为 float 的元素将会浮动在布局的左侧class 名为 text 的 div 元素将会在它后面并环绕它。文字环绕着浮动元素我们可以通过给 text 元素建立 BFC 来阻挡这种环绕行为。12345.text {      overflow: auto;}text 元素建立 BFC 后就不再环绕浮动元素了该方法也是我们创建浮动布局的基本方式。还需注意的是浮动一个元素时也会给该元素创建 BFC也就是说此时 .float 与 .text 都是 BFC这也是无论右侧高度低于还是高于左侧两者都不会互相围绕的原因。创建一个 BFC 的常用方式除了使用 overflow 外 一些其他的 CSS 属性也可以创建 BFC比如上面我们所见浮动一个元素也可以为该元素创建 BFC浮动元素会包裹它内部的所有元素。还有以下几种方式可以创建 BFC使用 position: absolute 或者 position fixed。使用 display: inline-block、display: table-cell 或者 display: table-caption其中 table-cell 和 table-caption是表格相关 HTML 元素的对应默认 CSS 值所以当你创建表格每个表格单元都会自动创建 BFC。另外当使用 multi-column layout 多列布局时使用 colum-span: all 也可以创建 BFC。Flex弹性 和 Grid网格 布局中的元素也会自动创建类似 BFC 的机制只是它们被称为 Flex Formatting Context弹性格式上下文和 Grid Formatting Context(网格格式上下文)。这反映了它们所参与的布局类型。一个 Block Formatting Context块级格式上下文表明他内部的元素参与了块级布局一个 弹性格式上下文意味着它内部的元素参与了弹性布局。在实践中这几种布局的结果是相似的浮动元素会被包裹、外边距不会叠加。创建 BFC 的新方式使用 overflow 或其他的方法创建 BFC 时会有两个问题。第一个是这些方法本身是有自身的设计目的的所以在使用它们创建 BFC 时会可能产生副作用。例如使用 overflow 创建 BFC 后在某些情况下你可能会看到出现一个滚动条或者元素内容被削减。这是由于 overflow 属性是设计被用来让你告诉浏览器如何定义元素的溢出状态的。浏览器执行了它最基本的定义。另一个问题是即使在没有出现副作用的情况下使用 overflow 也可能会使另一个开发人员感到困惑。他们可能会各种猜想这里为啥要把 overflow 的值设为 auto 或 scroll原开发人员做这个意义何在原开发人员是想让这里出现滚动条吗最安全的做法应该是创建一个 BFC 时不会有任何副作用它内部的元素都安安全全的呆在这个小布局里这种方法不会引起任何意想不到的问题也可以让开发者意图清晰。CSS 工作组也十分认同这种想法所以他们定制了一个新的属性值display: flow-root。你可以使用 display: flow-root 安全的创建 BFC 来解决本文中提到的各种问题包括包裹浮动元素、阻止外边距叠加、阻止环绕浮动元素。caniuse 上 display: flow-root 各浏览器支持情况浏览器对该属性值的支持目前还是有限的如果你觉得这个属性值很方便请投票去让 Edge 也支持它。不过无论如何你现在应该已经理解了什么是 BFC以及如何使用 overflow 或其他方法来包裹浮动以及知道了 BFC 可以阻止元素去环绕浮动元素如果你想使用弹性或网格布局可以在一些不支持他们的浏览器中使用 BFC 的这些特性做降级处理。理解浏览器如何布置网页是非常基础的。 虽然有时看起来无关紧要但是这些小知识可以加快创建和调试 CSS 布局所需的时间。“CSS布局中BFC的详细介绍”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注辰迅云网站,小编将为大家输出更多高质量的实用文章!...

这篇文章主要介绍js如何修改html的title标题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!js修改html title的方法:1、使用“document.title="需要设置的值";”语句;2、使用“$('title').html('新值')”或“$('title').text('新值')”语句语句。本教程操作环境:windows7系统、javascript1.8.5&&jquery1.7.2版、Dell G3电脑。方法1:document.title方式经过测试,还可通过document.title 设置title的值。document.title = '需要设置的值';例子<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>hello</title> </head> <body> <script type="text/javascript"> document.title = '亿速云'; </script> </body></html>方法2:利用jQuery的html()或text()方法当然如果你的项目里面依赖jQuery,可以使用jq的方法设置。jq中两种方式都可以实现$('title').html('需要设置的值') $('title').text('需要设置的值')例子<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>hello</title> <script src="js/jquery-1.7.2.min.js"></script> </head> <body> <script type="text/javascript"> // $('title').html('亿速云'); $('title').text('亿速云'); </script> </body></html>以上是“js如何修改html的title标题”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注辰迅云资讯频道!...

这篇文章主要为大家展示了“Xcode如何解清理缓存和垃圾文件”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Xcode如何解清理缓存和垃圾文件”这篇文章吧。一、清理Xcode中的垃圾文件1、前往Xcode所在的文件目录:~/Library/Developer/Xcode。如下图:2、进入目录后,可以看到Xcode文件中包含了如下几个文件夹:(1) Archives 存放的是Xcode打包时生成的文件,这里面的文件可以全部删掉。(2) DerivedData 存放的是build生成的项目索引、build输出以及日志,这里的文件可以全部删除。(3) iOS DeviceSupport 存放的是模拟器,对于你不需要的一些模拟器你可以删掉。即使不小心删掉了,也是可以重新下载的。其他几个文件所占的内存不多,可以不用去管它了。就上面几个文件夹我就清理了30G。以上是“Xcode如何解清理缓存和垃圾文件”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注辰迅云资讯频道!...

如何离线安装vue环境

2021/9/4 21:42:45

这篇文章将为大家详细讲解有关如何离线安装vue环境,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。离线安装vue环境的方法:1、cmd运行命令“npm config get cache”;2、内网电脑安装nodejs;3、内网全局安装目录;4、内网命令安装离线依赖包;5、把vue项目复制到内网;6、查看全局命令是否正常即可。本文操作环境:windows7系统、vue/cli 3.12.1版,DELL G3电脑。怎么离线安装vue环境?离线搭建vue环境运行项目步骤1、复制本地(外网电脑npm-cache缓存目录)cmd运行命令 npm config get cache2、内网电脑安装nodejsU盘或者光盘复制到内网电脑 安装即可3、内网全局安装目录命令行运行 npm root -g 查看全局安装目录;然后把npm-cache缓存目录复制到npm目录里面(如果放到同级会报错)4、内网命令安装离线依赖包npm install --cache ./npm-cache --optional --cache-min 99999999999 --shrinkwrap false yarnnpm install --cache ./npm-cache --optional --cache-min 99999999999 --shrinkwrap false webpacknpm install --cache ./npm-cache --optional --cache-min 99999999999 --shrinkwrap false webpack-clinpm install --cache ./npm-cache --optional --cache-min 99999999999 --shrinkwrap false @vue/cli@35、把vue项目复制到内网 包括node_modules文件夹 (注意 mac和windows依赖包不能共用)6、查看全局命令是否正常 npm list -global --debth 0正常异常解决办法:npm root -g命令找到npm文件夹删除与npm目录同级的node_modules文件夹把npm-cache文件夹放到npm目录里面运行项目  yarn run serve关于“如何离线安装vue环境”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。...

shell脚本中数组的用法

2021/9/4 21:38:15

本篇内容介绍了“shell脚本中数组的用法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!问题描述:某个员工的linux系统有大量重复的软件(版本不同),导致使用yum安装软件时报错。现在需要将重复的软件找出来,将低版本的软件删掉。执行rpm -qa | sort 显示如下:[root@cws85 ~]# rpm -qa | sort a52dec-0.7.4-27.el7.x86_64 aalib-libs-1.4.0-0.22.rc5.el7.x86_64 abattis-cantarell-fonts-0.0.25-1.el7.noarch abrt-2.1.11-52.el7.centos.x86_64 abrt-addon-ccpp-2.1.11-52.el7.centos.x86_64 abrt-addon-kerneloops-2.1.11-52.el7.centos.x86_64 abrt-addon-pstoreoops-2.1.11-52.el7.centos.x86_64 abrt-addon-python-2.1.11-52.el7.centos.x86_64 abrt-addon-vmcore-2.1.11-52.el7.centos.x86_64 abrt-addon-xorg-2.1.11-52.el7.centos.x86_64 abrt-cli-2.1.11-52.el7.centos.x86_64 abrt-console-notification-2.1.11-52.el7.centos.x86_64 abrt-dbus-2.1.11-52.el7.centos.x86_64 abrt-desktop-2.1.11-52.el7.centos.x86_64 abrt-gui-2.1.11-52.el7.centos.x86_64 abrt-gui-libs-2.1.11-52.el7.centos.x86_64 abrt-java-connector-1.0.6-12.el7.x86_64 abrt-libs-2.1.11-52.el7.centos.x86_64 abrt-python-2.1.11-52.el7.centos.x86_64 abrt-retrace-client-2.1.11-52.el7.centos.x86_64 abrt-tui-2.1.11-52.el7.centos.x86_64 accountsservice-0.6.50-4.el7.1.x86_64 accountsservice-libs-0.6.50-4.el7.1.x86_64 acl-2.2.51-14.el7.x86_64 adcli-0.8.1-6.el7_6.1.x86_64 adwaita-cursor-theme-3.28.0-1.el7.noarch adwaita-gtk2-theme-3.28-2.el7.x86_64 adwaita-icon-theme-3.28.0-1.el7.noarch adwaita-qt5-1.0-1.el7.x86_64 aic94xx-firmware-30-6.el7.noarch alsa-firmware-1.0.28-2.el7.noarch alsa-lib-1.1.6-2.el7.x86_64 alsa-plugins-pulseaudio-1.1.6-1.el7.x86_64 alsa-tools-firmware-1.1.0-1.el7.x86_64 alsa-utils-1.1.6-1.el7.x86_64 anaconda-core-21.48.22.121-1.el7.centos.x86_64 anaconda-core-21.48.22.147-1.el7.centos.0.1.x86_64 anaconda-gui-21.48.22.147-1.el7.centos.0.1.x86_64 anaconda-tui-21.48.22.121-1.el7.centos.x86_64                 #这是重复软件的低版本anaconda-tui-21.48.22.147-1.el7.centos.x86_64          #这是重复软件的高版本anaconda-widgets-21.48.22.147-1.el7.centos.0.1.x86_64 ..........省略 总共2586个软件要求:如上所示,需要将低版本的软件删除,如下是例外:[root@cws85 ~]# rpm -qa | grep audit-libs-[0-9]  audit-libs-2.8.4-4.el7.i686audit-libs-2.8.4-4.el7.x86_64虽然是重复软件,但一个是x86_64,一个是i686,这样不能删除,只能删除重复的_x86_64结尾的软件数组:脚本中用到了数组,下面是数组的部分内容概述:1.数组定义:declare -a  数组名    #定义索引数组,下标从0开始declare -A 数组名    #定义关联数组,下标为任意字符2.数组赋值与复制:2.1.可以通过命令替换的方式给数组赋值: declare -a SOFT1=($(rpm -qa | sort))  #数组SOFT1保存着所有软件2.2.数组复制操作:linux2=(${linux1[@]}) #数组linux2复制了数组linux1的内容3.数组的字符串操作:3.1.字符串的操作符可以用在数组上,如:${#string} 用于数组 ${#array[@]},等等等等。3.2.数组遍历: for i in ${!SOFT[@]}  #注意加上感叹号可以遍历数组中的值,假设SOFT的下标最大是2586,通过for循环可以遍历完数组,i的值从0依次到2586。脚本内容:#!/bin/bashdeclare -a SOFT1=($(rpm -qa | sort))      #数组SOFT1保存所有软件名称for i in ${!SOFT1[*]}                 #遍历数组SOFT1 do   declare -a SOFT2[$i]=${SOFT1[$i]%%-[0-9]*}        #数组SOFT2复制数组SOFT1的部分内容,%%是字符串截取符号,相当于去掉软件的版本号,只保留软件名称 donefor i in $(seq 0 $((${#SOFT2[@]}-1)))        #遍历数组SOFT2  do     let "j=$i+5"        for (( ;i<j;j--))            #i小于j时跳出循环,循环执行5次       do         if [ "${SOFT2[$i]}" == "${SOFT2[$j]}" ]     #测试是否有重复软件           then              declare -a SOFT3=($(rpm -qa | grep "^${SOFT2[$i]}-[0-9]" | sort))    #如果软件有重复,执行rpm -qa | grep 重复软件名,赋值给数组SOFT3              if (( "${#SOFT3[@]}" < 2 ))     #检测数组SOFT3的下标个数是否小于2(多加一层保险)                then                   echo "${SOFT2[$i]} no repeat version" >>/tmp/soft  && continue    #小于2输出该软件没有重复的版本              elif (( "${#SOFT3[@]}" > 2 ))     #如果下标大于2,也就是(rpm -qa | grep 重复软件)有多于2个软件                then                   X86=0 I686=0           #初始化两个变量,用于后面比较                   for i in ${!SOFT3[*]}      #遍历数组SOFT3                     do                       [[ "${SOFT3[$i]##*.}" == "i686" ]] && I686=$((I686+1)) || X86=$((X86+1))     #如果软件名结尾是i686,那么变量I686加1,否则X86加1                     done                       (( "$X86" >= "$I686" )) && echo "${SOFT3[0]} can1 delete" >>/tmp/soft      #如果X86值大于I686,输出软件能够删除               elif (( "${#SOFT3[@]}" == 2 ))         #如果下标等于2,也就是(rpm -qa | grep 重复软件)有两个                then                   [[ "${SOFT3[0]##*.}" == "i686" || "${SOFT3[1]##*.}" == "i686" ]] && { echo "${SOFT3[0]} only two packages but has I686" >>/tmp/soft ; continue ; }          #两个软件里只要有1个是i686结尾的,输出不能删除                   echo "${SOFT3[0]} can2 delete" >>/tmp/soft              fi         fi     done  done脚本说明:1.数组SOFT1保存所有软件的完整名称,数组SOFT2是通过数组复制加上字符串的替换,截取出不带版本名称的软件名,比如 SOFT1[4]=abrt-addon-ccpp-2.1.11-52.el7.centos.x86_64,  SOFT2[4]=abrt-addon-ccpp。2.利用for循环遍历数组SOFT2来检测那些是重复软件,如下:for i in $(seq 0 $((${#SOFT2[@]}-1)))       #遍历数组SOFT2do          let  "j=$i+5"       #j比i大5,用于测试某个软件名与它后面的5个软件名是否相等,因为是通过rpm -qa | sort排序过,所以软件名都是按照字母顺序排的,比较5个就可以了。       for (( ;i<j;j--))                  do             if [ "${SOFT2[$i]}" == "${SOFT2[$j]}" ]         #比较是否有重复软件名3.如果有重复,需要处理软件后缀名的问题,只有重复的以X86结尾的软件名才输出该软件可以删除。利用数组SOFT3=($(rpm -qa | grep "^${SOFT2[$i]}-[0-9]" | sort)) 来保存搜索出的重复软件,然后在进行判断比较脚本输出结果:输出被重定向到文件里,文件内容如下:anaconda-core-21.48.22.121-1.el7.centos.x86_64 can2 deleteanaconda-tui-21.48.22.121-1.el7.centos.x86_64 can2 deleteaudit-libs-2.8.4-4.el7.i686 only two packages but has I686avahi-libs-0.6.31-17.el7.x86_64 can2 deletebzip2-libs-1.0.6-13.el7.i686 only two packages but has I686copy-jdk-configs-2.2-5.el7_4.noarch can2 deletecracklib-2.9.0-11.el7.i686 only two packages but has I686cryptsetup-libs-1.7.4-3.el7_4.1.x86_64 can2 deletedbus-1.10.24-13.el7_6.x86_64 can2 deletedbus-libs-1.10.24-13.el7_6.x86_64 can2 deletedevice-mapper-event-libs-1.02.149-10.el7_6.3.x86_64 can2 deleteelfutils-libelf-0.172-2.el7.i686 only two packages but has I686elfutils-libs-0.172-2.el7.i686 only two packages but has I686fprintd-0.5.0-4.0.el7_0.x86_64 can2 deletefreetype-2.8-12.el7_6.1.i686 only two packages but has I686glib2-2.54.2-2.el7.x86_64 can2 deleteglibc-2.17-260.el7_6.6.i686 only two packages but has I686........省略 总共81行,能删除的有52行(有少数错误,后面说明)脚本调试信息:sh -x 脚本名显示的部分内容如下:+ SOFT1=($(rpm -qa | sort))      #数组SOFT1保存完整软件名++ rpm -qa ++ sort + declare -a SOFT1 + for i in '${!SOFT1[*]}'                #遍历数组SOFT1 + declare -a 'SOFT2[0]=a52dec'      #给数组SOFT2赋值,只保留软件名+ for i in '${!SOFT1[*]}'+ declare -a 'SOFT2[1]=aalib-libs'+ for i in '${!SOFT1[*]}'+ declare -a 'SOFT2[2]=abattis-cantarell-fonts'+ for i in '${!SOFT1[*]}'+ declare -a 'SOFT2[3]=abrt'+ for i in '${!SOFT1[*]}'+ declare -a 'SOFT2[4]=abrt-addon-ccpp'+ ..............省略,总共2586个 ++ seq 0 2585    + for i in '$(seq 0 $((${#SOFT2[@]}-1)))'          #遍历数组SOFT2,测试哪些是重复软件+ let j=0+5       #总共比较5次+ (( 1 )) + (( i<j )) + '[' a52dec == abrt-addon-kerneloops ']'+ (( j-- ))+ (( i<j )) + '[' a52dec == abrt-addon-ccpp ']'+ (( j-- ))+ (( i<j )) + '[' a52dec == abrt ']'+ (( j-- ))+ (( i<j )) + '[' a52dec == abattis-cantarell-fonts ']'+ (( j-- ))+ (( i<j )) + '[' a52dec == aalib-libs ']'                             #a53dec...不是一个重复软件+ (( j-- ))+ (( i<j )) + for i in '$(seq 0 $((${#SOFT2[@]}-1)))'     #比较下一个,数组下标加1+ let j=1+5...........................................................................省略 + for i in '$(seq 0 $((${#SOFT2[@]}-1)))'+ let j=35+5             #数组下标到35+ (( 1 )) + (( i<j )) + '[' anaconda-core == anaconda-widgets ']'+ (( j-- ))+ (( i<j )) + '[' anaconda-core == anaconda-tui ']'+ (( j-- ))+ (( i<j )) + '[' anaconda-core == anaconda-tui ']'+ (( j-- ))+ (( i<j )) + '[' anaconda-core == anaconda-gui ']'+ (( j-- ))+ (( i<j )) + '[' anaconda-core == anaconda-core ']'                                 #这里找到重复软件+ SOFT3=($(rpm -qa | grep "^${SOFT2[$i]}-[0-9]" | sort))     #数组SOFT3赋值=(rpm -qa |grep ^anaconda-core-[0-9]|sort)++ rpm -qa ++ sort++ grep '^anaconda-core-[0-9]'+ declare -a SOFT3 + ((  2 < 2  )) + ((  2 > 2  )) + ((  2 == 2  ))      #刚好有两个包+ [[ x86_64 == i686 ]]     #第一个包后缀是x86_64+ [[ x86_64 == i686 ]]    #第二个包后缀是x86_64+ echo 'anaconda-core-21.48.22.121-1.el7.centos.x86_64 can2 delete'      #输出能删除+ ..........................省略脚本输出错误:脚本输出文件里总共有52行是能删除的软件,其中有几个是错误的,由于软件名称导致的错误,如下:错误1: 软件名称: 字符-数字-字符-版本号  导致判断错误java-1.8.0-openjdk-1.8.0.222.b10-0.el7_6.x86_64 can1 deletejava-1.8.0-openjdk-1.8.0.222.b10-0.el7_6.x86_64 can1 deleteSOFT2[$i]=${SOFT1[$i]%%-[0-9]*}  #问题就在截取软件名称上,SOFT2=java, 正确的应该是SOFT2=java-1.8.0-openjdk。错误2:错误的软件名称结尾,该软件没有以.X86或其他结尾gpg-pubkey-0c1289c0-58c6ad7d can1 deletegpg-pubkey-0c1289c0-58c6ad7d can1 deletegpg-pubkey-0c1289c0-58c6ad7d can1 delete在给SOFT1赋值的时候需要过滤掉这种没有以.X86或其他后缀结尾的软件总结:很少在脚本中用到数组,通过这个脚本加深了对数组的掌握与应用。不知道怎么解决脚本输出中的错误1这种问题,大部分的软件都能正确去掉版本号,个别的软件名就不行,感觉总会有漏洞。该脚本主要在于练习数组的应用,同时也能从二千多个软件里面找出重复软件,虽然有个别错误,但也会比用眼睛找重复软件好,对照着输出文件来删除软件会轻松很多。“shell脚本中数组的用法”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注辰迅云网站,小编将为大家输出更多高质量的实用文章!...

小编给大家分享一下如何使用springcloud+oauth2携带token去请求其他服务,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!springcloud+oauth3携带token去请求其他服务当从oauth3服务中获取到了token后携带该token去请求其他服务时,报出{     "error": "invalid_token",     "error_description": "Invalid access token: e5224346-ea39-49ff-bd0e-1b9aef3db1da"}需要在当前服务的配置文件配置#内置有user对象的地址,才能获取到同一个tokensecurity.oauth3.resource.user-info-uri=http://localhost:8003/api/usersecurity.oauth3.resource.prefer-token-info=falsespringcloud 微服务之间传递token在springcloud 微服务中大部分是通过token来验证用户的,那么有个问题,假设现在有A服务,B服务,外部使用RESTApi请求调用A服务,在请求头上有token字段,A服务使用完后,B服务也要使用,如何才能把token也转发到B服务呢,最差的解决办法就是吧token放到请求参数中,但是这样第一个是明文传输,第二个是比较麻烦,前端每次都要加个参数。这里可以使用Feign的RequestInterceptor,把request里的请求参数包括请求头全部复制到feign的request里,但是直接使用一般情况下HttpServletRequest上下文对象是为空的,其实加个配置就可以解决。1、服务A中 application.yml 加入如下配置hystrix:  command:    default:      execution:        isolation:          strategy: SEMAPHORE  #加上这个就可以获取到HttpServletRequest          thread:            timeoutInMilliseconds: 100002、服务A中加入 FeginInterceptor@Configurationpublic class FeginInterceptor implements RequestInterceptor {     @Override    public void apply(RequestTemplate requestTemplate) {        try {            Map<String,String> headers = getHeaders();            for(String headerName : headers.keySet()){                requestTemplate.header(headerName, headers.get(headerName));            }        }catch (Exception e){            e.printStackTrace();        }     }     private Map<String, String> getHeaders(){         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();         Map<String, String> map = new LinkedHashMap<>();         Enumeration<String> enumeration = request.getHeaderNames();         while (enumeration.hasMoreElements()) {             String key = enumeration.nextElement();             String value = request.getHeader(key);             map.put(key, value);         }         return map;     } }若服务B或C也想传递token,加上上述A配置即可~看完了这篇文章,相信你对“如何使用springcloud+oauth2携带token去请求其他服务”有了一定的了解,如果想了解更多相关知识,欢迎关注辰迅云资讯频道,感谢各位的阅读!...

这篇文章将为大家详细讲解有关如何解决微服务中用户token处理到的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。关于用户token处理到的坑当采用前后台完全分离,以微服务架构的搭建时。在搭建微服务过程中,由于每个服务都是独立的应用,这样就会造成一个统一用户的问题。当用户从这个用户管理系统中登录后,在其他系统的如何判断用户是否已经登录的问题。目前常用的有以下几种方案:1、session 、redis共享处理2、Header存储token机制3、用户每个接口加入token参数其中3方案最简单,但是要求每个调用接口都需要传入token参数。我的前期采用的是这种方案。整体测试及使用结果还不错。方案2 是要求在进行请求时将token参数加入header中,由于涉及了自定义header参数,因此如果进行跨域访问时,会过不了Html预检功能。如果要处理这种预检,需要先进行options请求的处理。因此我在前台进行options请求,先将options请求返回200这样才能保证请求的继续执行。如果采用同一个域名的情况下,可以避免这种情况。方案3 在要求我们加入一个spring-session-data-redis的依赖。然后启动redishttpsession功能。但是我在使用过程中遇到不少问题。但是当多个项目启动这个功能时,会出现session冲突问题,造成每次请求的sessionid发生变化。微服务服务间调用传递token微服务间的调用通常我们使用FeignClient来实现。那么如何在调用的时候传递token来保证服务间调用的安全校验呢?没错,我们可以配置一个拦截器。该拦截器的功能就是在请求发出去前在header中添加token。代码如下@Componentpublic class FeignHeaderInterceptor implements RequestInterceptor {     @Override    public void apply(RequestTemplate template) {         template.header(HttpHeaders.AUTHORIZATION, "token");     } }RequestInterceptor是feign提供的接口该接口只有一个方法:public interface RequestInterceptor {   void apply(RequestTemplate template); }这样被调用的服务就可以在header中拿到token来做校验了。关于“如何解决微服务中用户token处理到的问题”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。...

小编给大家分享一下Laravel中Collection使用场景是什么,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!求和需求:遍历$orders 数组,求price 的和。<?php// 引入packagerequire __DIR__ . '/vendor/autoload.php'; $orders = [[     'id'            =>      1,     'user_id'       =>      1,     'number'        =>      '13908080808',     'status'        =>      0,     'fee'           =>      10,     'discount'      =>      44,     'order_products'=> [         ['order_id'=>1,'product_id'=>1,'param'=>'6寸','price'=>555.00,'product'=>['id'=>1,'name'=>'蛋糕名称','images'=>[]]],         ['order_id'=>1,'product_id'=>1,'param'=>'7寸','price'=>333.00,'product'=>['id'=>1,'name'=>'蛋糕名称','images'=>[]]],     ], ]];undefined$sum = 0;foreach ($orders as $order) {     foreach ($order['order_products'] as $item) {         $sum += $item['price'];     } }echo $sum;undefined$sum = collect($orders)->map(function($order){     return $order['order_products']; })->flatten(1)->map(function($order){     return $order['price']; })->sum();echo $sum;map:遍历集合,返回一个新的集合。flatten:将多维数组转换为一维。sum:返回数组的和。undefined$sum = collect($orders)->flatMap(function($order){     return $order['order_products']; })->pluck('price')->sum();echo $sum;flatMap:和map 类似,不过区别在于flatMap 可以直接使用返回的新集合。undefined$sum = collect($orders)->flatMap(function($order){     return $order['order_products']; })->sum('price');sum:可以接收一个列名作为参数进行求和。格式化数据需求:将如下结构的数组,格式化成下面的新数组。// 带格式化数组$gates = [     'BaiYun_A_A17',     'BeiJing_J7',     'ShuangLiu_K203',     'HongQiao_A157',     'A2',     'BaiYun_B_B230'];// 新数组$boards = [     'A17',     'J7',     'K203',     'A157',     'A2',     'B230'];undefined$res = [];foreach($gates as $key => $gate) {     if(strpos($gate, '_') === false) {         $res[$key] = $gate;     }else{         $offset = strrpos($gate, '_') + 1;         $res[$key] = mb_substr($gate , $offset);     } } var_dump($res);undefined$res = collect($gates)->map(function($gate) {     $parts = explode('_', $gate);     return end($parts); });undefined$res = collect($gates)->map(function($gate) {     return collect(explode('_', $gate))->last(); })->toArray();explode:将字符串进行分割成数组last:获取最后一个元素统计GitHub Event首先,通过此链接获取到个人事件json。一个 PushEvent计 5 分,一个 CreateEvent 计 4 分,一个 IssueCommentEvent计 3 分,一个 IssueCommentEvent 计 2 分,除此之外的其它类型的事件计 1 分,计算当前用户的时间得分总和。$opts = [         'http' => [                 'method' => 'GET',                 'header' => [                         'User-Agent: PHP'                ]         ] ]; $context = stream_context_create($opts); $events = json_decode(file_get_contents('http://api.github.com/users/0xAiKang/events', false, $context), true);undefined$eventTypes = []; // 事件类型$score = 0; // 总得分foreach ($events as $event) {     $eventTypes[] = $event['type']; }foreach($eventTypes as $eventType) {     switch ($eventType) {         case 'PushEvent':         $score += 5;         break;         case 'CreateEvent':         $score += 4;         break;         case 'IssueEvent':         $score += 3;         break;         case 'IssueCommentEvent':         $score += 2;         break;         default:         $score += 1;         break;     } }undefined$score = $events->pluck('type')->map(function($eventType) {    switch ($eventType) {       case 'PushEvent':       return 5;       case 'CreateEvent':       return 4;       case 'IssueEvent':       return 3;       case 'IssueCommentEvent':       return 2;       default:       return 1;   } })->sum();使用集合的链式编程,可以很好地解决上面那种多次遍历的问题。undefined$score = $events->pluck('type')->map(function($eventType) {    return collect([        'PushEvent'=> 5,        'CreateEvent'=> 4,        'IssueEvent'=> 3,        'IssueCommentEvent'=> 2   ])->get($eventType, 1); // 如果不存在则默认等于1})->sum();undefinedclass GithubScore {     private $events;     private function __construct($events){         $this->events = $events;     }     public static function score($events) {         return (new static($events))->scoreEvents();     }     private function scoreEvents() {         return $this->events->pluck('type')->map(function($eventType){             return $this->lookupEventScore($eventType, 1);         })->sum();     }     public function lookupEventScore($eventType, $default_value) {        return collect([            'PushEvent'=> 5,            'CreateEvent'=> 4,            'IssueEvent'=> 3,            'IssueCommentEvent'=> 2       ])->get($eventType, $default_value); // 如果不存在则默认等于1    } } var_dump(GithubScore::score($events));格式化数据需求:将以下数据格式化成新的结构。$messages = [     'Should be working now for all Providers.',     'If you see one where spaces are in the title let me know.',     'But there should not have blank in the key of config or .env file.' ];// 格式化之后的结果- Should be working now for all Providers. \n - If you see one where spaces are in the title let me know. \n - But there should not have blank in the key of config or .env file.undefined$comment = '- ' . array_shift($messages);foreach ($messages as $message) {     $comment .= "\n -  ${message}"; } var_dump($comment);undefined$comment = collect($messages)->map(function($message){     return '- ' . $message; })->implode("\n"); var_dump($comment);多个数组求差需求:两组数据分别代表去年的营收和今年的营收,求每个月的盈亏情况。$lastYear = [    6345.75,    9839.45,    7134.60,    9479.50,    9928.0,    8652.00,    7658.40,    10245.40,    7889.40,    3892.40,    3638.40,    2339.40];$thisYear = [    6145.75,    6895.00,    3434.00,    9349350,    9478.60,    7652.80,    4758.40,    10945.40,    3689.40,    8992.40,    7588.40,    2239.40];undefined$profit = [];foreach($thisYear as $key => $monthly){     $profit[$key] = $monthly - $lastYear[$key]; } var_dump($profit);undefined$profit = collect($thisYear)->zip($lastYear)->map(function($monthly){     return $monthly->first() - $monthly->last(); });zip:将给定数组的值与相应索引处的原集合的值合并在一起。创建lookup 数组需求:将如下数组格式化成下面的结果:$employees = [     [         'name' => 'example',         'email' => 'example@exmaple.com',         'company' => 'example Inc.'    ],     [         'name' => 'Lucy',         'email' => 'lucy@example.com',         'company' => 'ibm Inc.'    ],     [         'name' => 'Taylor',         'email' => 'toylor@laravel.com',         'company'=>'Laravel Inc.'    ] ];// 格式化之后的结果$lookup = [     'example' => 'example@example.com',     'Lucy' => ‘lucy@example.com’,     'Taylor'=> 'toylor@laravel.com'];undefined$emails = [];foreach ($employees as $key => $value) {     $emails[$value['name']] = $value['email']; }undefined$emails = collect($employees)->reduce(function($emailLookup, $employee){     $emailLookup[$employee['name']] = $employee['email'];     return $emailLookup; },[]);reduce:将每次迭代的结果传递给下一次迭代直到集合减少为单个值。undefined$emails = collect($employees)->pluck('name', 'email');看完了这篇文章,相信你对“Laravel中Collection使用场景是什么”有了一定的了解,如果想了解更多相关知识,欢迎关注辰迅云资讯频道,感谢各位的阅读!...