原文地址http://nikic.github.io/2017/04/14/PHP-7-Virtual-machine.html

写这篇文章的目的是基于 php7,阐述 Zend Virtual Machine 的内部实现。这不是一篇综合描述,我将尽可能地覆盖到所有重要的部分和细节。

本文的描述对象是 php7.2 版本,但是几乎所有的特性都已经应用在了 php7.0/7.1 中了。然而,它们同 php5.x 系列 VM 的不同之处同样也很重要,我会很有耐心的同步描述。

这篇文章主要是从指令的角度来阐述,只有在末尾花了少量篇幅描述了 C 语言实现 VM 的细节。但是在文章开始之前,我想先提供一些实现 VM 的主要代码文件:...

原文地址http://blog.jpauli.tech/2017/01/12/threads-and-php.html

前言

PHP 和线程,单凭这简短的几个字,就足以写一本书。像往常一样,我们不会这么做,但是会给出一定程度上跟这个话题相关的信息与细节。让我们从一些人在谈论这个话题时通常感到的困惑开始,PHP 不是一种线程语言, PHP 的内核没有使用线程,而且 PHP 天生也不允许用户层代码通过任何方式使用多线程作为并发机制。

因此 PHP 跟其他一些技术有很大的区别,例如 Java。Java 不仅自身使用了大量的线程,它还允许用户通过编程来是用线程。然而,PHP 不适用线程是有它的原因的。

PHP 内核没有使用线程,主要是为了...

在阅读优秀的 c 语言开源程式的时候,我们经常会看到各种复杂的声明,顿时会让我们怀疑人生,怀疑自己是否真的看得懂 c 语言。然而冷静三秒钟,透过现象看本质,发现牛人写的代码并不是“天书”, 也是很好懂的,关键是要冷静和耐心去阅读。

从中的一个例子说起

1(*(void(*)())0)()

下面我们来一步步分析:

我们知道变量的声明方式为:

1int a;

函数的声明方式为:

1int fn();

指针的声明方式为:

1int *a = 10;

函数指针的声明方式为:

1int (*fn)(); //fn 是一个指向返回int型的函数的指针

函数指针的调用方式:

 1typedef int (*fn_type)();
 2
 3...

preface

在之前的文章中,我们已经实现了一些 object handlers 来将我们的 ArrayBuffer 整合到 php 中。但是美中不足的是,我们的 ArrayBufferView 并不支持迭代器操作。也就是它不能像 php 中的数组那样使用foreach来遍历。 那么,我们接下来就来看看迭代器在内核中是如何实现的,并且给我们的 ArrayBufferView 也增加一个迭代器。

get_iterator handler

内核中的迭代器跟用户端的IteratorAggregate接口功能是一样的。一个具有迭代功能的类都有一个get_iterator处理器,它会返回一个zend_object_iterator *类...

Object Handlers

在前面的博文中,已经介绍过一些 object handlers 了,也特别介绍了如何通过指定 handlers 来创建一个自定义的结构和使用clone_obj来对自定义的结构进行克隆操作。 然而,这只是开始:在 php 中,几乎所有的对象操作,都可以通过 object handlers 来实现,而且所有的魔术方法和魔术接口在内核中都是实现了对应的 object handler。此外, 一些 handlers 并没有开放给用户端的 php,例如,内部类可以自定义类的比较操作,而使用 php 代码是无法实现的。

由于 php 中有很多不同的 object handlers,这里只挑几个来讨论,其它的只给...

ArrayBuffer 简介

ArrayBuffer 又叫二进制数组,是一个用来表示通用的,固定长度的二进制数据缓冲区。你不能直接操纵 ArrayBuffer 的内容, 而是创建一个表示特定格式的 buffer 的类型化数组对象(也叫做数据视图对象)来对 buffer 的内容进行读写操作。

我最早了解 ArrayBuffer 是从 JavaScript 开始的,具体的用法和 api 可以参考JavaScript 标准库--ArrayBuffer

那么接下来,我们就给 PHP 扩展一个简单的 ArrayBuffer,顺便巩固一下php 扩展开发之自定义对象的存储

定义 ArrayBuffer 的数据结构和相关 handlers...

前言

对于 php 扩展开发,很多人可能已经不那么陌生了,zend 引擎为了们提供了非常丰富了函数和 macro,来帮助我们很快速的创建一个标准的 php 类,然而,当我们在使用自定义的数据结构(struct), 并想把我们自己定义的数据结构封装成 php 的类的时候可能就会有些困惑,因为我们都知道 php 中的所有变量都是通过 zval 来存储的,而我们自定义的数据结构要怎样才能和 zval 实现完美的对接呢? 以前我通常采用的一种方式就是使用 zend 引擎提供的资源类型,因为资源类型的封装中包含了通用的数据类型,而且有很丰富的函数来操作资源,所以使用起来很简单也很方便。然而,强大的 zend 引擎真的没有其他方式扩展数据结构...

hashtable

哈希表又叫散列表,是实现字典操作的中有效数据结构。通常来说,一个 hash table 包含了一个数据,其中的数据通过 index 来访问。 而 hash table 的基本原理就是通过 hash 函数建立起所有可能的 index 与其对应的位置的联系。一个 hash 函数接收一个 key,返回其 hash code, key 的类型是可变的,而 hash code 是一个整型。

由于计算一个 hash 值和通过 index 访问一个数据都是常量级的时间复杂度,所以我们可以通过这中特性实现常量级时间复杂度的查找。 如果一个 hash 函数能够保证不会有两个不同的 key 生成相同的 hash 值,...

struct

在 c 语言中,结构体(struct)是一种复合数据类型,用来将一系列相同或不同类型的变量聚集在同一个内存区间内并赋予同一个名字,使得通过一个指针就能访问集合中的所有成员。结构体中可以包含许多简单或符合数据类型,因此从内存分配上看,有点类似数组,而从变量组织上看,又类似于面向对象编程语言中的类。

定义 struct

定义一个 struct 非常简单,使用struct关键字即可。

1struct student {
2    char *name;
3    int age;
4};

struct 的初始化

通常有四种常用的 struct 初始化方式。

1.定义并初始化

1struct {
2    char...

1、JNI 基础

JNI 中定义了一下类型来对应到相应的 Java 的数据类型:

1. Java 基本数据类型: jint,jbyte,jshort,jlong,jfloat,jdouble,jchar,jboolean分别对应 Java 中的int,byte,short,long,float,double,charboolean

2. Java 引用类型: jobject对应java.lang.object。同时也定义了下列子类型:

  • jclass对应java.lang.Class
  • jstring对应java.lang.String
  • jthrowable对应java.lang.Throwable
  • jarray对应 Java ...