分类
PHP后端

PHP中什么是生成器(Generator)?怎么使用?

PHP中什么是生成器(Generator)?怎么使用?下面本篇文章带大家深入讲解一下PHP 中的生成器,希望对大家有所帮助!

谈到驾驶,速度并非一切。但在网络上,速度变得与众不同。你的应用程序越快,用户体验越好。这篇文章是关于 PHP 生成器的,那么我们为什么要讨论速度呢?你很快就会发现,生成器在速度和内存的管理上发挥着巨大的作用。

PHP生成器是什么?

生成器是在 PHP 5.5 版本中添加的,它提供了一种简单的方法来遍历数据,而不需要在内存中构建数组。是不是有点疑惑?那举一个例子,展示使用生成器是一个好方式。

首先,创建一个 generator.php 文件,它将贯穿我们整个例子。创建文件之后,我们添加一段代码。

function getRange ($max = 10) {
    $array = [];
    for ($i = 1; $i < $max; $i++) {
        $array[] = $i;
    }
    return $array;
} 

foreach (getRange(15) as $range) {
    echo "Dataset {$range}";
}

我们可以在创建 generator.php 文件所在目录中快速启动一个内置的 PHP 服务器:

php -S localhost:8000

如果用浏览器打开 http://localhost:8000/generator.php ,我们应该看到这样的结果:

这段代码的自解释性并不是太好. 让我们稍微改动一下代码

foreach (getRange(PHP_INT_MAX) as $range) {
    echo "Dataset {$range}";
}

有点遗憾的是 PHP 耗尽了内存. 你能够想到的解决方法可能包括增加 php.ini 文件中 memory_limit 的上限. 不过平心而论,这个脚本既不高效又占用内存, 我们需要的是一个高效且占用内存低的脚本。

使用生成器

让我们在上面定义相同的函数,用相同的值 PHP_INT_MAX 调用它,然后再次运行。但是这一次我们将创建一个生成器函数。

function getRange ($max = 10) {
    for ($i = 1; $i < $max; $i++) {
        yield $i;
    }
}

foreach (getRange(PHP_INT_MAX) as $range) {
    echo "Dataset {$range}";
}

解析 getRange 函数,这次,我们只循环遍历值和 yield 输出。 yield 与返回值类似,因为它也是从函数返回一个值,但唯一的区别是 yield 只会在需要时返回一个值,并且不会尝试将整个数据集保留在内存中。

如果您转到浏览器,您应该会看到页面上显示的数据。给定适当的时间,浏览器最终显示数据。

注意: 生成器只能在函数中使用。

为什么要使用生成器

有时候,我们可能会遇到想要解析一个庞大的数据集(也可能是日志文件),也可能对一个大型数据库的结果集执行计算,等等情况。我们不想让这些数据全部加载到内存中。我们应该尽可能的保存相应的内存状态。数据不一定要很大——无论数据有多小,生成器都是有效的。别忘了,我们的目的是使用更少的内存来尽可能快的处理数据。

总结

生成器提供了难以忽视的显著性的能提升。大多数的时候,我们不需要高配置的服务器来运行代码。我们只需要做一点重构,生成器是非常有用的,我们应该多多使用它们

英文原文地址:

https://scotch.io/tutorials/understanding-php-generators

以上就是PHP中什么是生成器(Generator)?怎么使用?的详细内容,更多请关注php中文网其它相关文章!

分类
WEB前端

CSS布局(Display、Position、Overflow、Float)

布局说明

基本布局属性

Display(显示)

display属性设置一个元素应如何显示。
display:none可以隐藏某个元素,且隐藏的元素不会占用任何空间。也就是说,该元素不但被隐藏了,而且该元素原本占用的空间也会从页面布局中消失
display:block-显示为块级元素
display:inline-显示为内联元素
display:inline-block-显示为内联块元素,表现为同行显示并可修改宽高内边距等属性

Visibility(可见)

visibility属性指定一个元素应可见还是隐藏
visibility:hidden可以隐藏某个元素,但隐藏的元素仍需占用与未隐藏之前一样的空间。也就是说,该元素虽然被隐藏了,但仍然会影响布局。
visibility:collape一般的元素的表现与visibility:hidden一样,也即其会占用空间。但如果该元素是与table相关的元素,列如table row、table column、table column group、table column group等,其表现却跟display:none一样,也即其占用的空间会释放。

Position(定位)

position属性指定了元素的定位类型
1、staticHTML元素的默认值,即没有定位,遵循正常的文档流对象
2、fixed固定定位元素的位置相对于浏览器窗口是固定位置
1、Fixed定位使元素的位置与文档流无关,因此不占据空间
2、Fixed定位的元素和其它元素重叠

// 右上角显示
p.pos_fixed
{
    position:fixed;
    top:30px;
    right:5px;
}

relative相对定位元素的定位时相对其正常位置

移动相对定位元素,但它原本所占的空间不会改变

// 从元素的原始左侧位置减去 20 像素。(左移20px)
h2.pos_left
{
   position:relative;
   left:-20px;
}

Overflow(溢出)

overflow属性规定当内容溢出元素框时发生的事情
注意:overflow属性值工作于指定高度块元素
1、visible内容不会被修剪,会呈现在元素框之外(默认值)
2、hidden内容会被修剪,并且其余内容是不可见的
3、 scroll内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容
4、auto如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容

Float(浮动)

float会使元素向左或向右移动,其周围的元素也会重新排列。往往是用于图像,但它在布局时一样非常有用。使元素的位置与文档流无关,因为不占据空间

// 图片浮动显示
.image-list {
    float:left;
    margin:5px
  }

Clear(清除浮动)

clear属性指定元素两侧不能出现浮动元素
元素浮动后,周围的元素会重新排列,为了避免这种情况,使用clear属性

// text_line 元素左右两边不能出现浮动元素
.text_line
{
    clear:both;
}

z-index(顺序)

z-index设置元素的堆叠顺序
可定义为一个值(整数数字),越大代表越置前,如可定义为:z-index:9999。若定义为-1,代表为最底层

flex布局 & grid布局

flex布局
display: flex
display: inline-flex
Flex 布局是轴线布局,只能指定”项目”针对轴线的位置,可以看作是一维布局。
参考:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html grid布局
display: grid
display: inline-grid
Grid 布局则是将容器划分成”行”和”列”,产生单元格,然后指定”项目所在”的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大。
参考:https://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html

分类
WEB前端

Vue动态权限路由addRoutes执行初次白屏解决方法。

需求:

当用户登录,或者已经登录状态下刷新和重进web端,除了普通的路由配置(login、UserInfo、home、404等),还需要用户的权限路由,需要根据用户信息拿到当前用户的权限路由,动态添加路由。

问题:

addRoutes()之后第一次访问被添加的路由会白屏,这是因为刚刚addRoutes()就立刻访问被添加的路由,然而此时addRoutes()没有执行结束,因而找不到刚刚被添加的路由导致白屏。因此需要从新访问一次路由才行。

router.beforeEach( async (to, from, next) => {
 const token = sessionStorage.getItem('access_token')
 // 存在 token 说明已经登录
 if (token) {
   // 登录过就不能访问登录界面,需要中断这一次路由守卫,执行下一次路由守卫,并且下一次守卫的to是主页'
   if (to.path === '/login') {
     next({ path: '/' })
   }
   // 保存在store中路由不为空则放行 (如果执行了刷新操作,则 store 里的路由为空,此时需要重新添加路由)
   if (Routerobj已存在) {  
     //放行
     next()
   } else {
      //这里还需要保存Routerobj  防止重复进入这。
    await let Router =  getAsyncRouterobj()  //拿异步Routerobj
     router.addRoutes(Router)  //需要添加的路由
     // 如果 addRoutes 并未完成,路由守卫会一层一层的执行执行,直到 addRoutes 完成,找到对应的路由
     next({ ...to, replace: true })
   }
 } else {
   // 未登录时,注意 :在这里也许你的项目不只有 logon 不需要登录 ,register 等其他不需要登录的页面也需要处理
   if (to.path !== '/logon') {
     next({ path: '/logon' })
   } else {
     next()
   }
 }

解决:

使用next({ …to,replace: true})来确保addRoutes()时动态添加的路由已经被完全加载上去。

分类
WEB前端

动效网站收集整理

动效、动画库:

网上的总结:http://www.360doc.com/content/16/0430/14/21340737_555133634.shtml

https://animate.style/作用:关于标签元素一些小动效,像移入移出,强调显示

http://bouncejs.com/
这个网站挺好,根据网站提供的基础特效,然后可以调整参数来修改对应的特效。但这个库没用过。

http://ianlunn.github.io/Hover/
这个是鼠标移入移出元素变化的动效

动效工具:

网络上此类工具的整理总结:https://www.evget.com/article/2017/4/17/26111.html

https://www.w3cways.com/css3-animation-tool自己加动效然后可以直接生成代码的工具

搜索相应动效的网址:优点是上面得动画效果基本都有现成得代码。

1.codePen:这个是国外人弄得网站,搜索得时候尽量写英文,比如搜索钟表得动效,输入:css3 clock 然后回车。
随便看一看效果得话,常用得搜索关键字,css3/css3 animate/css3 transition/css3 transform
https://codepen.io/search/pens?q=css3+clock

2.jsrun.net
这个跟codePen一个意思,中文得所以方便很多。

3.https://techbrood.com/
这个跟前两个差不多。

动效插件网站:插件网站各有优劣,有的效果代码下载不了

https://www.html5tricks.com/ 例子基本都可以下载下来
17素材:https://www.17sucai.com/pins/tag/5664.html
JS特效代码:https://www.jsdaima.com/#top
JS组件-js组件:http://www.lovewebgames.com/jsmodule/index.html
轮子工厂:http://www.wheelsfactory.cn/#/
jquery插件库:https://www.jq22.com/
a5下载:https://www.a5xiazai.com/

分类
PHP后端

使用JWT,封号,踢人,强制用户退出到底怎么实现?

JSON Web Token(JWT)作为目前最流行的跨域认证方案大家都不陌生了吧。很多系统都在使用JWT替代session认证,这两者有啥区别呢?
简言之,JWT是将认证后的数据保存在客户端,session是保存在服务器端。
使用JWT替代session认证后,服务器不用维护session,分布式环境下不需要单点存储session。因为JWT的自解释性,只要验证JWT是否合法就OK啦。大大提升了系统的可扩展性,特别适合当下微服务大行其道的大环境。
加入一个
但是。。。
老板想要实现踢人,封号怎么办呢?
第一个想法就是颁布jwt时,把jwt存到一个中心redis中。每次访问验证jwt时看看redis里是否有这个token,没有这个token就认证失败。踢人封号只用把用户关联的jwt删除掉就ok了!就可以愉快的回家抱媳妇了(抱歉可能你没有)。
且慢,这么玩完全违背了jwt的初衷,服务器又变了有状态了,何苦脱裤子放屁呢,直接用session不就完了?
讲真的jwt的设计也不太适合这样的场景。

那如果我们非要实现强制用户登出要怎么办呢

可以采用类似oauth2.0协议中的做法,认证后颁布2个token,access token和refresh token。

  • access token访问令牌为一个JWT,设置一个较短的过期时间,比如1小时。访问令牌每次调用后端服务都需要携带,往返网络的频率非常高,暴露的可能性就越大,设置较短的过期时间也可以降低安全风险。
  • refresh token刷新令牌,可以不为JWT,设置一个较长的过期时间,比如1个月。刷新令牌主要用来换取新的access token。因为其仅在访问令牌要失效或已经失效时才会被传递给服务端,较长的过期时间并不会有太大的安全风险。颁发token的时候,仅将刷新令牌保存在redis并设置过期时间。当使用刷新令牌换取新的访问令牌时,需要判断redis里是否存在该刷新令牌,如果不存在,则刷新失败,用户就需要重新登录。

客户端要长时间维护登录态,就需要当访问令牌失效后,自动使用刷新令牌获取新的访问令牌。或者在访问令牌失效之前,提前刷新令牌。

现在我们想要踢人,只需要将用户相关的刷新令牌从redis里删除。当前的访问令牌失效后,自然也没有办法再刷新令牌了。从而达到强制用户登出的目的。

这么设计有个缺陷就是强制用户登出不是及时的。需要有一个等待访问令牌过期的时间。如果希望及时性高点,可以将访问令牌的过期时间设置短一点,但刷新token的频率就会升高。这个需要根据自己的业务进行权衡。
每次调用服务api时仍然是原汁原味的jwt无状态认证,无需访问任何中心存储。仅在刷新访问令牌的时候需要访问中心存储。也算是一种折中的方案。

分类
WEB前端

为什么推荐Vue框架?Vue框架总结之vue的优点

一、基本介绍

  1. Vue.js目前最火的的一个前端框架,三大主流前端框架之一。
  2. Vue.js是一套构建用户界面的框架(一套完整的解决方案,对项目侵入性大,中途需要跟换框架则需要重构整个项目),只关注视图层,易上手,有配套的第三方类库。
  3. 提高开发效率,帮助减少不必要的dom操作;双向数据绑定,通过框架提供的指令,前端只需要关注业务逻辑,不再关心dom如何渲染。

二、前端的MVVM

  1. 前端视图层的概念,主要把每个页面分成了M(Model)、V(View)、VM(VM ViewModel)。VM是其中核心,M和V间的调度者。
  2. M,保存的是每个页面中单独的数据(比如要渲染页面表格,ajax请求到后台的你个数组,此数据即为M)。
  3. V,每个页面的html结构。
  4. VM,一个调度者,分割了M和V,M和V不直接关联,通过中间的VM。V想要保存数据到M,都要有VM做中间处理;V想要渲染页面,需要调用VM,VM从M中取数据。
  5. 前端中使用MVVM思想,主要让开发更方便,MVVM提供了数据的双向绑定(由VM提供)。

三、为什么推荐Vue

  • 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
  • 简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
  • 双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
  • 组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
  • 视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
  • 虚拟DOM:dom操作是非常耗费性能的,不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
  • 运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。