php 数组循环-PHP实现刮刮卡、大转盘抽奖概率,其实很简单!

2023-08-21 0 4,682 百度已收录

链接最好放在公众号里php 数组循环,过期后可以更改,所以这也是文章中不收录的原因。 请看清楚这段话:如有需要,可以关注“PHP自学中心”,回复相应关键词,获取链接并提取代码。感谢您的支持和信任

Yii2视频教程
链接:https://pan.baidu.com/s/1kU6fbKz 
密码:本公众号里回复关键词:yii2

php 数组循环-PHP实现刮刮卡、大转盘抽奖概率,其实很简单!

文章正文

php 数组循环-PHP实现刮刮卡、大转盘抽奖概率,其实很简单!

本文实例为大家分享php彩票概率算法,可用于刮刮卡、大转盘等中奖算法。 使用方法非常简单。 代码中有详细的注释供大家参考。 具体内容如下

/*
 * 经典的概率算法,
 * $proArr是一个预先设置的数组,
 * 假设数组为:array(100,200,300,400),
 * 开始是从1,1000 这个概率范围内筛选第一个数是否在他的出现概率范围之内, 
 * 如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,
 * 在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。
 * 这样 筛选到最终,总会有一个数满足要求。
 * 就相当于去一个箱子里摸东西,
 * 第一个不是,第二个不是,第三个还不是,那最后一个一定是。
 * 这个算法简单,而且效率非常高,
 * 这个算法在大数据量的项目中效率非常棒。
 */

function get_rand($proArr) 
  $result = ''
  //概率数组的总概率精度 
  $proSum = array_sum($proArr); 
  //概率数组循环 
  foreach ($proArr as $key => $proCur) { 
    $randNum = mt_rand(1, $proSum); 
    if ($randNum <= $proCur) { 
      $result = $key; 
      break
    } else { 
      $proSum -= $proCur; 
    }    
  } 
  unset ($proArr); 
  return $result; 

颁奖场

php 数组循环-PHP实现刮刮卡、大转盘抽奖概率,其实很简单!

这里的奖励是一个二维数组。 您可以自己组装数据,也可以从后台将数据存储到数据库中,然后读取。 请记住php 数组循环,它是一个二维数组。

/*
 * 奖项数组
 * 是一个二维数组,记录了所有本次抽奖的奖项信息,
 * 其中id表示中奖等级,prize表示奖品,v表示中奖概率。
 * 注意其中的v必须为整数,你可以将对应的 奖项的v设置成0,即意味着该奖项抽中的几率是0,
 * 数组中v的总和(基数),基数越大越能体现概率的准确性。
 * 本例中v的总和为100,那么平板电脑对应的 中奖概率就是1%,
 * 如果v的总和是10000,那中奖概率就是万分之一了。
 * 
 */

$prize_arr = array
  '0' => array('id'=>1,'prize'=>'平板电脑','v'=>1), 
  '1' => array('id'=>2,'prize'=>'数码相机','v'=>5), 
  '2' => array('id'=>3,'prize'=>'音箱设备','v'=>10), 
  '3' => array('id'=>4,'prize'=>'4G优盘','v'=>12), 
  '4' => array('id'=>5,'prize'=>'10Q币','v'=>22), 
  '5' => array('id'=>6,'prize'=>'下次没准就能中哦','v'=>50), 
); 

前端请求数据

每次后端请求数据,比如刮刮卡,转动转盘,循环发送奖励。

/*
 * 每次前端页面的请求,PHP循环奖项设置数组,
 * 通过概率计算函数get_rand获取抽中的奖项id。
 * 将中奖奖品保存在数组$res['yes']中,
 * 而剩下的未中奖的信息保存在$res['no']中,
 * 最后输出json个数数据给前端页面。
 */

foreach ($prize_arr as $key => $val) { 
  $arr[$val['id']] = $val['v']; 

$rid = get_rand($arr); //根据概率获取奖项id 

$res['yes'] = $prize_arr[$rid-1]['prize']; //中奖项 
unset($prize_arr[$rid-1]); //将中奖项从数组中剔除,剩下未中奖项 
shuffle($prize_arr); //打乱数组顺序 
for($i=0;$i<count($prize_arr);$i++){ 
  $pr[] = $prize_arr[$i]['prize']; 

$res['no'] = $pr; 
print_r($res); 

文章正文

PHP的设计理念和特点 PHP的核心框架

PHP核心架构如右图,从下到上可以简单分为四层:

PHP的执行过程

PHP实现了典型的动态语言执行过程:接收到一段代码后,经过词法分析、语法分析等阶段,将源程序翻译成指令(操作码),然后ZEND虚拟机依次执行这些指令完毕。 PHP本身是用C实现的,所以最终调用的都是C函数。 其实PHP可以看成是C语言开发的软件。

PHP执行的核心就是一一翻译后的指令,即操作码。

操作码是PHP程序执行的最基本单位。 一个操作码由两个参数(op1、op2)、返回值和处理函数组成。 PHP程序最终被翻译成一系列操作码处理函数。

几种常见的处理函数:

Zend 引擎简介

端引擎作为PHP的核心,有很多经典的设计机制,主要有:

4.1 实现HashTable数据组织:

HashTable 是 Zend 的核心数据结构。 几乎所有常用功能都是用PHP实现的。 我们所知道的PHP领域就是它的典型应用。 而且,zend内部,函数符号表、全局变量等功能也是基于hashtable实现的。

Zendhashtable实现了一种典型的哈希表哈希结构,同时通过附加一个单向数组提供了正向和反向遍历字段的功能。其结构如右图所示

可以看到,hashtable中既有key->value的哈希结构,也有单向数组模式,这样就可以非常方便地支持快速查找和线性遍历。

哈希结构:Zend的哈希结构是典型的哈希表模型,它以数组的形式解决冲突。 需要注意的是,zend的hashtable是一种自减的数据结构。 当哈希表的数量已满时,它会动态扩展其容量2倍并重新定位元素。 两者的初始大小均为 8。 另外,在进行key->value快速查找时,zend本身也做了一些优化,通过以空间换时间来提高速度。 例如,在每个元素中,使用一个变量nKeyLength来标记按键的粗细,以便快速判断。

单向数组:Zendhashtable 通过数组结构实现元素的线性遍历。 理论上来说,使用双向数组进行遍历就足够了。 使用单向数组的主要目的是快速删除和防止遍历。 Zendhashtable 是一个复合结构。 当用作形式参数时,它支持常见的关联链表,也可以用作顺序索引号,甚至允许两者混合。

PHP关联字段:关联字段是典型的hash_table应用。 一次查询过程会经过以下步骤(从代码中可以看出,这是一个普通的哈希查询过程,减少了一些快速判断,以加快查找速度):

getKeyHashValue h;
index = n & nTableMask;
Bucket *p = arBucket[index];
while (p) {
  if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
      RETURN p->data;   
  }
  p=p->next;
}
RETURN FALTURE;

PHP索引字段:索引字段是我们常见的字段,通过下标访问。 比如arr[0],ZendHashTable内部进行了归一化,同时将hash值和nKeyLength(0)也赋值给了索引类型key。 内部成员变量nNextFreeElement是当前分配的最大id,每次push后都会手动加1。 正是这些规范化过程让 PHP 实现了关联和非关联的混合。 由于push操作的特殊性,PHP链表中索引键的顺序并不是由下标的大小决定的php 判断字符串,而是由push的顺序决定的。如arr[1]=2; arr[2]=3; 对于 double 类型的 key,ZendHashTable 会把他当作索引 key

4.2 PHP变量实现原理:

PHP是弱类型语言,并不严格区分变量的类型。 PHP在声明变量时不需要指定类型。 PHP 可能在程序执行期间执行变量类型的隐式转换。 与其他强类型语言一样,程序中也可以进行显式类型转换。 PHP变量可以分为简单类型(int、string、bool)、集合类型(array、resource、object)和常量(const)。 上面所有的变量都是底层相同的结构zval。

Zval是zend中另一个特别重要的数据结构。 它用于标记和实现PHP变量。 其数据结构如下:

Zval结构主要由三部分组成:

type:指定变量描述的类型(整数、字符串、数组等)

refcount&is_ref:用于实现引用计数(前面详细介绍过)

value:核心部分,存储变量的实际数据

Zvalue用于保存变量的实际数据。 由于要存储多种类型,所以zvalue是一个union,它也实现了弱类型。

PHP变量类型与其实际存储的对应关系如下:

IS_LONG   -> lvalue
IS_DOUBLE -> dvalue
IS_ARRAY  -> ht
IS_STRING -> str
IS_RESOURCE -> lvalue

4.2.1 整数和浮点变量

整数和浮点数是PHP中的基本类型之一,也是简单的变量。 对于整数和浮点数,将对应的值直接存储在zvalue中。 其类型分别为long和double。

从zvalue结构可以看出,对于整数类型,与C等强类型语言不同,PHP不区分int、unsignedint、long、longlong等类型。 对于它来说,只有一种整数类型,那就是长整型。 由此可见,在PHP上,整数的取值范围是由编译器的位数决定的,而不是固定的。

对于浮点数来说,和整数类似,它不区分float和double,而只区分double的一种。

在PHP中,如果整数范围超出范围怎么办? 在这些情况下,它将被手动转换为 double 类型。 这点一定要小心,因为很多花招都是由此形成的。

4.2.2 字符变量

与整数一样,字符变量是 PHP 中的原始类型和简单变量。 从zvalue结构可以看出,在PHP中,字符串是由指向实际数据的指针和宽度结构组成的,与C++中的字符串类似。 因为厚度是用实际变量表示的,与c不同,它的字符串可以是2补码数据(包括),而在PHP中,求字符串宽度strlen是一个O(1)的操作。

当进行添加、修改、追加字符串操作时,PHP会重新分配显存来生成新的字符串。 最后,出于安全考虑,PHP在生成字符串时仍然会在末尾添加

常见的字符串拼接方法及速度对比:

假设有4个变量如下:strA='123';strB='456';intA=123;intB=456;

现对以下字符串拼接方式进行对比和说明:

1 res = strA.strB 且 res = "strAstrB"

在这些情况下,zend会重新malloc一块显存并进行相应处理,其速度也正常。

2strA=strA.strB

这些是最快的,zend会直接根据当前strA进行relloc,防止重复复制

3res=intA.intB

这些速度很慢,因为需要隐式格式转换,在实际编程中要注意尽量避免

4strA=sprintf(“%s%s”,strA,strB);

这将是最慢的形式,因为sprintf不是PHP中的语言结构,它需要花费大量时间来识别和处理格式,而且它的机制也是malloc。 但sprintf的形式可读性最强,实际中可以根据具体情况灵活选择。

4.2.3 字段变量

PHP的链表自然是通过ZendHashTable来实现的。

如何实现foreach操作? 链表的foreach是通过遍历哈希表中的单向数组来完成的。 对于索引字段,foreach遍历的效率比for高很多,并且省略了key->value的查找。 计数操作直接调用HashTable->NumOfElements,O(1)操作。 对于像 '123' 这样的字符串,zend 会将其转换为整数形式。 arr['123'] 和 arr[123] 等效

4.2.4 资源变量

资源类型变量是PHP中最复杂的变量,也是复合结构。

PHP的zval可以表示很多种数据类型,很难完全描述自定义数据类型。 由于没有有效的方法来绘制此类复合结构,因此无法在其上使用传统运算符。 要解决这个问题,只需要通过本质上任意的标识符(标签)来引用指针即可。 这些方法称为资源。

在zval中,对于资源来说,lval作为指针,直接指向资源所在的地址。 资源可以是任意组合结构,我们熟悉的mysqli、fsock、memcached等都是资源。

如何使用资源:

1 注册:对于自定义数据类型,您希望将其用作资源。 首先,它需要注册,zend 会给它分配一个全局唯一的标识符。

2 获取资源变量:对于资源,zend维护一个id->实际数据的hash_tale。 对于资源,zval 中仅记录其 id。 取的时候,通过id找到hash_table中的具体值并返回。

3 资源破坏:资源的数据类型多种多样。 Zend 本身没有办法销毁它。 因此,用户在注册资源时需要提供销毁函数。 当unset资源时,zend调用相应的函数来完成销毁。 同时将其从全局资源表中删除。

资源可以持续存在多年,不仅是在引用它的所有变量超出范围之后,而且甚至在请求结束并形成新请求之后也是如此。 此类资源称为持久资源,因为它们在 SAPI 的整个生命周期中持续存在,除非被故意破坏。 很多情况下,持久化资源可以在一定程度上提高性能。 比如我们常见的mysql_pconnect,持久化资源通过pemalloc分配显存,这样请求结束时就不会被释放。 对于zend来说,两者没有区别。

4-3. PHP 变量管理 - 引用计数和写时复制:

引用计数在显存回收、字符串操作等方面应用尤其广泛。Zval的引用计数是通过成员变量is_ref和ref_count来实现的。 通过引用计数,多个变量可以共享相同的数据。 防止频繁复印造成的大量消耗。 zend在进行形参操作时,将变量指向与ref_count++相同的zval,而unset操作时,对应的ref_count-1。 只有当ref_count减为0时,才会执行实际的销毁操作。 如果是引用参数,zend 会将 is_ref 更改为 1。

PHP变量通过引用计数实现变量共享数据,那么如果其中一个变量值改变了怎么办? 当尝试写入一个变量时,如果Zend发现该变量指向的zval被多个变量共享,它将复制一个ref_count为1的zval,并减少原始zval的refcount。 这个过程称为“zval分离”。 可见zend只有在发生写操作时才会进行复制操作,因此也称为copy-on-write(写时复制)

对于引用变量,其要求与非引用类型相反。 引用参数的变量必须是绑定的,改变一个变量会改变所有绑定的变量。

4-4. PHP局部变量和全局变量的实现:

PHP中局部变量和全局变量是如何实现的? 对于一个请求,PHP随时可以看到两个符号表(symbol_table和active_symbol_table),后者用于维护全局变量。 前者是指向当前活动变量符号表的指针。 当程序进入一个函数时,zend会为其分配一个符号表x,并将active_symbol_table指向a。 通过这种方法,实现了全局变量和局部变量的区分。

获取变量值:PHP的符号表是通过hash_table实现的,为每个变量分配一个唯一的标签。 获取时根据标签从表中找到对应的zval并返回。

在函数中使用全局变量:在函数中,我们可以通过显式声明global来使用全局变量。 在active_symbol_table中创建对symbol_table中同名变量的引用(引用变量的值需要更新你就一起更新)php 判断字符串,如果symbol_table中没有同名变量,则会首先创建的。

以上就是文章的全部内容。 有学习和经验交流的可以加小编为好友。 如果有技术问题可以一起解释、交流。 如果你是PHP的,小编还可以拉你进Momo技术群交流学习!

让学习成为一种习惯

学习|交流|分享|文章

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 php php 数组循环-PHP实现刮刮卡、大转盘抽奖概率,其实很简单! https://www.wkzy.net/game/137521.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务