PHP Generator的实现

对于Generator的实现,关键的数据结构是_zend_execute_data,已在这篇文章:PHP内核的一点探索——execute_data 介绍了。本文只是粗略的说明了Generator的实现~

Generator的创建


Generator的实现代码在Zend/zend_generators.c中,我们无法直接new一个Generator对象,如果直接new的话会报如下错误:

PHP Catchable fatal error: The "Generator" class is reserved for internal use and cannot be manually instantiated

在源码中可看到原因:

1
2
3
4
5
6
7
static zend_function *zend_generator_get_constructor(zval *object TSRMLS_DC) /* {{{ */
{
    zend_error(E_RECOVERABLE_ERROR, "The \"Generator\" class is reserved for internal use and cannot be manually instantiated");
    
    return NULL;
}
/* }}} */

Read more...

2016-04-12

PHP execute_data

这阵子想研究下PHP Generator的实现,发现对于Generator很重要的一个数据结构为_zend_execute_data,在PHP源码中通常是一个execute_data变量,与该变量相关的宏是#define EX(element) execute_data.element

查看了下opcode的执行,发现_zend_execute_data对于PHP代码的执行也是关键的数据结构。所以本文主要围绕该数据结构展开来讲~


Read more...

2016-03-24

PHP 协程

理解生成器


参考官方文档:Generators 生成器让我们快速、简单地实现一个迭代器,而不需要创建一个实现了Iterator接口的类后,再实例化出一个对象。

一个生成器长什么样?如下

1
2
3
4
5
6
<?php
function foo() {
    ……
    yield [$someValue];
    ……
}

与一般函数的区别在于:

  • 它不能return $notNULLValue(不能有,会报语法错误= =PHP Fatal error: Generators cannot return values using "return"),但可以是return;(相当于return NULL;其实当一个函数没有明确进行return时,PHP会自动为函数加入return;
  • 必须含有yield关键字(当生成器执行的时候,每次执行到yield都会中断,并且将$someValue作为返回值,如果有的话,没有则是返回NULL)。yield的具体语法见:Generator syntax
  • 它会被转换为Generator类的一个对象

Read more...

2016-03-20

MySQL Gtid复制方案学习

MySQL从5.6开始出了新的主从复制解决方案:Replication with Global Transaction Identifiers

GTID解决的问题:

  • 在整个复制集群中能够唯一的标识一个事务
  • 更方便的实效转移
  • 确保同一个事务只会被执行一次

GTID的限制:

  • 无法使用CREATE TABLE ... SELECT statements语句
  • 无法在事务中对非事务存储引擎进行更新
  • 无法在事务中使用CREATE TEMPORARY TABLE
  • 具体可参考:Restrictions on Replication with GTIDs

Read more...

2016-01-30

如何保障用户密码安全

如何安全存储密码


1、使用哈希算法直接对密码进行hash

md5(password)sha1(password)等,这种做法在当前时代已经不安全了,因为随着“彩虹表”不断变大,如果被拖库了,用户的密码就容易被反哈希出来。国内密码学专家王小云已成功破解了md5和sha1.


Read more...

2016-01-16

认识SQL注入的类型

SQL的注入类型有以下5种:

  1. Boolean-based blind SQL injection(布尔型注入)
  2. Error-based SQL injection(报错型注入)
  3. UNION query SQL injection(可联合查询注入)
  4. Stacked queries SQL injection(可多语句查询注入)
  5. Time-based blind SQL injection(基于时间延迟注入)

Read more...

2015-11-21

MySQL ibdata 存储空间的回收

前言


在MySQL <= 5.6.5,innodb_file_per_table默认为0,即InnoDB表的数据都会存储在共享表空间ibdata中,除此之外ibdata还存储着数据字典、双写缓冲区、undo log等。

当innodb_file_per_table为0时,ibdata会不断增大,有时会导致磁盘空间不足。通常是InnoDB表的数据导致的,undo log是次要原因。 因为undo log的增加通常是在事务较为繁忙的时候,且事务中做了大量的更新操作,但是undo log占用的空间却可以被重用。InnoDB的purge线程就是负责清理不需要的undo log空间以供其他的undo log使用。

那么为何InnoDB表的数据会成为ibdata增大的主要原因?因为InnoDB表的数据被delete之后的空间是无法被InnoDB重用的,需要人为干预处理= =


Read more...

2015-11-21 InnoDB