浏览代码

Php 7.3 fix (#5434)

* Inherit from message instead of implement

When regestering class (implmenets other class) during MINIT, zend_class_implements
would call zend_class_entry->interface_gets_implemented(). In PHP-7.3 interface_gets_implemented shares the same location with create_object.
However, during MINIT, the global object storeage hasn't been initialized. And thus, caused segment fault in php 7.3.

* Use zend_string_init where interned string may be the value.
zend_string_dup will keep using the existing interned string.
In php 7.3, interned string cannot be destroyed from user's code.

* Uncommment debug code

* Use latest phpunit for each php versions

* Revert change in Dockerfile

* Update php test to use the new docker image

* Update composer

* Change docker organization

* Update phpunit

* Debug phpunit

* Store phpunit into bin dir in docker image

* Install valgrind to docker

* Fix compatibility test

* Remove generated_service_test from compatibility c extension test

* Update 32bit php test to the new docker image

* Install bison

* Fix build.sh

* Fix DOCKERIMAGE_PREFIX

* Fix basename

* Add comment to build_and_run_docker2.sh

* Remove commented code

* Fix comments
Paul Yang 6 年之前
父节点
当前提交
d7c4409589

+ 2 - 0
.gitignore

@@ -145,7 +145,9 @@ php/ext/google/protobuf/Makefile.objects
 php/ext/google/protobuf/acinclude.m4
 php/ext/google/protobuf/build/
 php/ext/google/protobuf/config.h
+php/ext/google/protobuf/config.h.in~
 php/ext/google/protobuf/config.nice
+php/ext/google/protobuf/configure.ac
 php/ext/google/protobuf/configure.in
 php/ext/google/protobuf/mkinstalldirs
 php/ext/google/protobuf/run-tests.php

+ 2 - 1
kokoro/linux/32-bit/build.sh

@@ -10,7 +10,8 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/32-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/php_32bit
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
 export TEST_SET="php_all_32"

+ 12 - 2
kokoro/linux/build_and_run_docker.sh

@@ -3,6 +3,8 @@
 # Builds docker image and runs a command under it.
 # This is a generic script that is configured with the following variables:
 #
+# DOCKERHUB_ORGANIZATION - The organization on docker hub storing the
+# Dockerfile.
 # DOCKERFILE_DIR - Directory in which Dockerfile file is located.
 # DOCKER_RUN_SCRIPT - Script to run under docker (relative to protobuf repo root)
 # OUTPUT_DIR - Directory that will be copied from inside docker after finishing.
@@ -15,8 +17,16 @@ git_root=$(pwd)
 cd -
 
 # Use image name based on Dockerfile sha1
-DOCKERHUB_ORGANIZATION=grpctesting/protobuf
-DOCKER_IMAGE_NAME=${DOCKERHUB_ORGANIZATION}_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
+if [ -z "$DOCKERHUB_ORGANIZATION" ]
+then
+  DOCKERHUB_ORGANIZATION=grpctesting/protobuf
+  DOCKER_IMAGE_NAME=${DOCKERHUB_ORGANIZATION}_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
+else
+  # TODO(teboring): Remove this when all tests have been migrated to separate
+  # docker images.
+  DOCKERFILE_PREFIX=$(basename $DOCKERFILE_DIR)
+  DOCKER_IMAGE_NAME=${DOCKERHUB_ORGANIZATION}/${DOCKERFILE_PREFIX}_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
+fi
 
 # Pull dockerimage from Dockerhub
 docker pull $DOCKER_IMAGE_NAME

+ 17 - 12
kokoro/linux/dockerfile/test/php/Dockerfile

@@ -79,8 +79,8 @@ RUN cd php-src \
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-4.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-5.5 \
-  && mv phpunit /usr/local/php-5.5-zts
+  && cp phpunit /usr/local/php-5.5/bin \
+  && mv phpunit /usr/local/php-5.5-zts/bin
 
 # php 5.6
 RUN cd php-src \
@@ -109,8 +109,8 @@ RUN cd php-src \
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-5.6 \
-  && mv phpunit /usr/local/php-5.6-zts
+  && cp phpunit /usr/local/php-5.6/bin \
+  && mv phpunit /usr/local/php-5.6-zts/bin
 
 # php 7.0
 RUN cd php-src \
@@ -139,8 +139,8 @@ RUN cd php-src \
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-6.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-7.0 \
-  && mv phpunit /usr/local/php-7.0-zts
+  && cp phpunit /usr/local/php-7.0/bin \
+  && mv phpunit /usr/local/php-7.0-zts/bin
 
 # php 7.1
 RUN cd php-src \
@@ -169,8 +169,8 @@ RUN cd php-src \
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-7.1 \
-  && mv phpunit /usr/local/php-7.1-zts
+  && cp phpunit /usr/local/php-7.1/bin \
+  && mv phpunit /usr/local/php-7.1-zts/bin
 
 # php 7.2
 RUN cd php-src \
@@ -199,8 +199,8 @@ RUN cd php-src \
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-7.2 \
-  && mv phpunit /usr/local/php-7.2-zts
+  && cp phpunit /usr/local/php-7.2/bin \
+  && mv phpunit /usr/local/php-7.2-zts/bin
 
 # php 7.3
 RUN cd php-src \
@@ -229,5 +229,10 @@ RUN cd php-src \
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-7.3 \
-  && mv phpunit /usr/local/php-7.3-zts
+  && cp phpunit /usr/local/php-7.3/bin \
+  && mv phpunit /usr/local/php-7.3-zts/bin
+
+# Install php dependencies
+RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
+  valgrind \
+  && apt-get clean

+ 224 - 0
kokoro/linux/dockerfile/test/php_32bit/Dockerfile

@@ -0,0 +1,224 @@
+FROM 32bit/debian:jessie
+
+# Install dependencies.  We start with the basic ones require to build protoc
+# and the C++ build
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  git \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  parallel \
+  time \
+  wget \
+  && apt-get clean
+
+# Install php dependencies
+RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
+  bison \
+  php5 \
+  libcurl4-openssl-dev \
+  libssl-dev \
+  libxml2-dev \
+  unzip \
+  zlib1g-dev \
+  pkg-config \
+  && apt-get clean
+
+# Install other dependencies
+RUN wget http://ftp.gnu.org/gnu/bison/bison-2.6.4.tar.gz -O /var/local/bison-2.6.4.tar.gz
+RUN cd /var/local \
+  && tar -zxvf bison-2.6.4.tar.gz \
+  && cd /var/local/bison-2.6.4 \
+  && ./configure \
+  && make \
+  && make install
+
+# Install composer
+RUN curl -sS https://getcomposer.org/installer | php
+RUN mv composer.phar /usr/local/bin/composer
+
+# Download php source code
+RUN git clone https://github.com/php/php-src
+
+# php 5.5
+RUN cd php-src \
+  && git checkout PHP-5.5.38 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-5.5 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-5.5-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-4.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-5.5/bin \
+  && mv phpunit /usr/local/php-5.5-zts/bin
+
+# php 5.6
+RUN cd php-src \
+  && git checkout PHP-5.6.39 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-5.6 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-5.6-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-5.6/bin \
+  && mv phpunit /usr/local/php-5.6-zts/bin
+
+# php 7.0
+RUN cd php-src \
+  && git checkout PHP-7.0.33 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.0 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.0-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-6.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-7.0/bin \
+  && mv phpunit /usr/local/php-7.0-zts/bin
+
+# php 7.1
+RUN cd php-src \
+  && git checkout PHP-7.1.25 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.1 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.1-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-7.1/bin \
+  && mv phpunit /usr/local/php-7.1-zts/bin
+
+# php 7.2
+RUN cd php-src \
+  && git checkout PHP-7.2.13 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.2 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.2-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-7.2/bin \
+  && mv phpunit /usr/local/php-7.2-zts/bin
+
+# php 7.3
+RUN cd php-src \
+  && git checkout PHP-7.3.0 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.3 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.3-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-7.3/bin \
+  && mv phpunit /usr/local/php-7.3-zts/bin
+
+# Install php dependencies
+RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
+  valgrind \
+  && apt-get clean

+ 2 - 1
kokoro/linux/php_all/build.sh

@@ -10,7 +10,8 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/php
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
 export TEST_SET="php_all"

+ 0 - 26
php/ext/google/protobuf/message.c

@@ -1231,7 +1231,6 @@ zend_class_entry* any_type;
 
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Any", Any, any)
-  zend_class_implements(any_type TSRMLS_CC, 1, message_type);
   zend_declare_property_string(any_type, "type_url", strlen("type_url"),
                                "" ,ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_string(any_type, "value", strlen("value"),
@@ -1421,7 +1420,6 @@ zend_class_entry* duration_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Duration",
                                  Duration, duration)
-  zend_class_implements(duration_type TSRMLS_CC, 1, message_type);
   zend_declare_property_long(duration_type, "seconds", strlen("seconds"),
                              0 ,ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_long(duration_type, "nanos", strlen("nanos"),
@@ -1457,7 +1455,6 @@ zend_class_entry* timestamp_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Timestamp",
                                  Timestamp, timestamp)
-  zend_class_implements(timestamp_type TSRMLS_CC, 1, message_type);
   zend_declare_property_long(timestamp_type, "seconds", strlen("seconds"),
                              0 ,ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_long(timestamp_type, "nanos", strlen("nanos"),
@@ -1650,7 +1647,6 @@ zend_class_entry* api_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Api",
                                  Api, api)
-  zend_class_implements(api_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(api_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(api_type, "methods", strlen("methods"),
@@ -1697,7 +1693,6 @@ zend_class_entry* bool_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\BoolValue",
                                  BoolValue, bool_value)
-  zend_class_implements(bool_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(bool_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -1726,7 +1721,6 @@ zend_class_entry* bytes_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\BytesValue",
                                  BytesValue, bytes_value)
-  zend_class_implements(bytes_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(bytes_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -1755,7 +1749,6 @@ zend_class_entry* double_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\DoubleValue",
                                  DoubleValue, double_value)
-  zend_class_implements(double_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(double_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -1792,7 +1785,6 @@ zend_class_entry* enum_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Enum",
                                  Enum, enum)
-  zend_class_implements(enum_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(enum_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(enum_type, "enumvalue", strlen("enumvalue"),
@@ -1837,7 +1829,6 @@ zend_class_entry* enum_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\EnumValue",
                                  EnumValue, enum_value)
-  zend_class_implements(enum_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(enum_value_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(enum_value_type, "number", strlen("number"),
@@ -1872,7 +1863,6 @@ zend_class_entry* field_mask_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\FieldMask",
                                  FieldMask, field_mask)
-  zend_class_implements(field_mask_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(field_mask_type, "paths", strlen("paths"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -1919,7 +1909,6 @@ zend_class_entry* field_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Field",
                                  Field, field)
-  zend_class_implements(field_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(field_type, "kind", strlen("kind"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(field_type, "cardinality", strlen("cardinality"),
@@ -1975,7 +1964,6 @@ zend_class_entry* float_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\FloatValue",
                                  FloatValue, float_value)
-  zend_class_implements(float_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(float_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2002,7 +1990,6 @@ zend_class_entry* empty_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\GPBEmpty",
                                  GPBEmpty, empty)
-  zend_class_implements(empty_type TSRMLS_CC, 1, message_type);
 PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(GPBEmpty, __construct) {
@@ -2028,7 +2015,6 @@ zend_class_entry* int32_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Int32Value",
                                  Int32Value, int32_value)
-  zend_class_implements(int32_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(int32_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2057,7 +2043,6 @@ zend_class_entry* int64_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Int64Value",
                                  Int64Value, int64_value)
-  zend_class_implements(int64_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(int64_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2086,7 +2071,6 @@ zend_class_entry* list_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\ListValue",
                                  ListValue, list_value)
-  zend_class_implements(list_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(list_value_type, "values", strlen("values"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2127,7 +2111,6 @@ zend_class_entry* method_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Method",
                                  Method, method)
-  zend_class_implements(method_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(method_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(method_type, "request_type_url", strlen("request_type_url"),
@@ -2176,7 +2159,6 @@ zend_class_entry* mixin_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Mixin",
                                  Mixin, mixin)
-  zend_class_implements(mixin_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(mixin_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(mixin_type, "root", strlen("root"),
@@ -2210,7 +2192,6 @@ zend_class_entry* option_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Option",
                                  Option, option)
-  zend_class_implements(option_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(option_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(option_type, "value", strlen("value"),
@@ -2242,7 +2223,6 @@ zend_class_entry* source_context_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\SourceContext",
                                  SourceContext, source_context)
-  zend_class_implements(source_context_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(source_context_type, "file_name", strlen("file_name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2271,7 +2251,6 @@ zend_class_entry* string_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\StringValue",
                                  StringValue, string_value)
-  zend_class_implements(string_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(string_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2300,7 +2279,6 @@ zend_class_entry* struct_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Struct",
                                  Struct, struct)
-  zend_class_implements(struct_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(struct_type, "fields", strlen("fields"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2339,7 +2317,6 @@ zend_class_entry* type_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Type",
                                  Type, type)
-  zend_class_implements(type_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(type_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(type_type, "fields", strlen("fields"),
@@ -2383,7 +2360,6 @@ zend_class_entry* u_int32_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\UInt32Value",
                                  UInt32Value, u_int32_value)
-  zend_class_implements(u_int32_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(u_int32_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2412,7 +2388,6 @@ zend_class_entry* u_int64_value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\UInt64Value",
                                  UInt64Value, u_int64_value)
-  zend_class_implements(u_int64_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(u_int64_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2452,7 +2427,6 @@ zend_class_entry* value_type;
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Value",
                                  Value, value)
-  zend_class_implements(value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(value_type, "kind", strlen("kind"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END

+ 4 - 2
php/ext/google/protobuf/protobuf.h

@@ -137,7 +137,8 @@
     const char* class_name = CLASSNAME;                                      \
     INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
                         LOWWERNAME##_methods);                               \
-    LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
+    LOWWERNAME##_type = zend_register_internal_class_ex(                     \
+        &class_type, message_type, NULL TSRMLS_CC);                          \
     LOWWERNAME##_type->create_object = message_create;                       \
     zend_do_inheritance(LOWWERNAME##_type, message_type TSRMLS_CC);
 #define PHP_PROTO_INIT_SUBMSGCLASS_END \
@@ -404,7 +405,8 @@ static inline int php_proto_zend_hash_get_current_data_ex(HashTable* ht,
     const char* class_name = CLASSNAME;                                      \
     INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
                         LOWWERNAME##_methods);                               \
-    LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
+    LOWWERNAME##_type = zend_register_internal_class_ex(                     \
+        &class_type, message_type TSRMLS_CC);                                \
     zend_do_inheritance(LOWWERNAME##_type, message_type TSRMLS_CC);
 #define PHP_PROTO_INIT_SUBMSGCLASS_END \
   }

+ 4 - 2
php/ext/google/protobuf/storage.c

@@ -180,7 +180,8 @@ bool native_slot_set_by_array(upb_fieldtype_t type,
       PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value),
                              Z_STRLEN_P(value), 1);
 #else
-      *(zend_string**)memory = zend_string_dup(Z_STR_P(value), 0);
+      *(zend_string**)memory =
+          zend_string_init(Z_STRVAL_P(value), Z_STRLEN_P(value), 0);
 #endif
       break;
     }
@@ -231,7 +232,8 @@ bool native_slot_set_by_map(upb_fieldtype_t type, const zend_class_entry* klass,
       PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value),
                              Z_STRLEN_P(value), 1);
 #else
-      *(zend_string**)memory = zend_string_dup(Z_STR_P(value), 0);
+      *(zend_string**)memory =
+          zend_string_init(Z_STRVAL_P(value), Z_STRLEN_P(value), 0);
 #endif
       break;
     }

+ 1 - 1
php/tests/array_test.php

@@ -7,7 +7,7 @@ use Google\Protobuf\Internal\GPBType;
 use Foo\TestMessage;
 use Foo\TestMessage\Sub;
 
-class RepeatedFieldTest extends PHPUnit_Framework_TestCase
+class RepeatedFieldTest extends \PHPUnit\Framework\TestCase
 {
 
     #########################################################

+ 4 - 0
php/tests/compatibility_test.sh

@@ -123,8 +123,12 @@ tests=( array_test.php encode_decode_test.php generated_class_test.php map_field
 sed -i.bak '/php_implementation_test.php/d' phpunit.xml
 sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml
 sed -i.bak 's/generated_phpdoc_test.php//g' tests/test.sh
+sed -i.bak 's/generated_service_test.php//g' tests/test.sh
 sed -i.bak '/memory_leak_test.php/d' tests/test.sh
 sed -i.bak '/^    public function testTimestamp()$/,/^    }$/d' tests/well_known_test.php
+sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/array_test.php
+sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/map_field_test.php
+sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/test_base.php
 for t in "${tests[@]}"
 do
   remove_error_test tests/$t

+ 6 - 0
php/tests/encode_decode_test.php

@@ -31,6 +31,7 @@ class EncodeDecodeTest extends TestBase
     {
         $m = new TestMessage();
         $m->mergeFromJsonString("{\"optionalInt32\":1}");
+        $this->assertEquals(1, $m->getOptionalInt32());
     }
 
     public function testDecodeTopLevelBoolValue()
@@ -276,6 +277,7 @@ class EncodeDecodeTest extends TestBase
         $to = new TestPackedMessage();
         $to->mergeFromString(TestUtil::getGoldenTestPackedMessage());
         TestUtil::assertTestPackedMessage($to);
+        $this->assertTrue(true);
     }
 
     public function testPackedDecodeUnpacked()
@@ -283,6 +285,7 @@ class EncodeDecodeTest extends TestBase
         $to = new TestPackedMessage();
         $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage());
         TestUtil::assertTestPackedMessage($to);
+        $this->assertTrue(true);
     }
 
     public function testUnpackedEncode()
@@ -298,6 +301,7 @@ class EncodeDecodeTest extends TestBase
         $to = new TestUnpackedMessage();
         $to->mergeFromString(TestUtil::getGoldenTestPackedMessage());
         TestUtil::assertTestPackedMessage($to);
+        $this->assertTrue(true);
     }
 
     public function testUnpackedDecodeUnpacked()
@@ -305,6 +309,7 @@ class EncodeDecodeTest extends TestBase
         $to = new TestUnpackedMessage();
         $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage());
         TestUtil::assertTestPackedMessage($to);
+        $this->assertTrue(true);
     }
 
     public function testDecodeInt64()
@@ -361,6 +366,7 @@ class EncodeDecodeTest extends TestBase
         $data = hex2bin('c80501');
         $m = new TestMessage();
         $m->mergeFromString($data);
+        $this->assertTrue(true);
     }
 
     public function testEncodeNegativeInt32()

+ 10 - 0
php/tests/generated_class_test.php

@@ -260,12 +260,14 @@ class GeneratedClassTest extends TestBase
     {
         $m = new TestMessage();
         $m->setOptionalNestedEnum(NestedEnum::ZERO);
+        $this->assertTrue(true);
     }
 
     public function testLegacyNestedEnum()
     {
         $m = new TestMessage();
         $m->setOptionalNestedEnum(\Foo\TestMessage_NestedEnum::ZERO);
+        $this->assertTrue(true);
     }
 
     public function testLegacyTypehintWithNestedEnums()
@@ -405,6 +407,7 @@ class GeneratedClassTest extends TestBase
           $m = new TestMessage();
           $hex = hex2bin("ff");
           $m->setOptionalBytes($hex);
+          $this->assertTrue(true);
       }
 
     #########################################################
@@ -709,6 +712,8 @@ class GeneratedClassTest extends TestBase
         // test nested messages
         $sub = new NoNamespaceMessage\NestedMessage();
         $n->setNestedMessage($sub);
+
+        $this->assertTrue(true);
     }
 
     public function testEnumWithoutNamespace()
@@ -718,6 +723,7 @@ class GeneratedClassTest extends TestBase
         $repeatedNoNamespaceEnum = $m->getRepeatedNoNamespaceEnum();
         $repeatedNoNamespaceEnum[] = NoNameSpaceEnum::VALUE_A;
         $m->setRepeatedNoNamespaceEnum($repeatedNoNamespaceEnum);
+        $this->assertTrue(true);
     }
 
     #########################################################
@@ -1262,6 +1268,8 @@ class GeneratedClassTest extends TestBase
         $m = \Upper_enum_value\NotAllowed::NULL;
         $m = \Upper_enum_value\NotAllowed::VOID;
         $m = \Upper_enum_value\NotAllowed::ITERABLE;
+
+        $this->assertTrue(true);
     }
 
     #########################################################
@@ -1297,6 +1305,7 @@ class GeneratedClassTest extends TestBase
     {
         $m = new testLowerCaseMessage();
         $n = testLowerCaseEnum::VALUE;
+        $this->assertTrue(true);
     }
 
     #########################################################
@@ -1363,6 +1372,7 @@ class GeneratedClassTest extends TestBase
         ]);
 
         TestUtil::assertTestMessage($m);
+        $this->assertTrue(true);
     }
 
     #########################################################

+ 1 - 1
php/tests/map_field_test.php

@@ -7,7 +7,7 @@ use Google\Protobuf\Internal\MapField;
 use Foo\TestMessage;
 use Foo\TestMessage\Sub;
 
-class MapFieldTest extends PHPUnit_Framework_TestCase {
+class MapFieldTest extends \PHPUnit\Framework\TestCase {
 
     #########################################################
     # Test int32 field.

+ 2 - 1
php/tests/test_base.php

@@ -4,7 +4,7 @@ use Foo\TestMessage;
 use Foo\TestEnum;
 use Foo\TestMessage\Sub;
 
-class TestBase extends PHPUnit_Framework_TestCase
+class TestBase extends \PHPUnit\Framework\TestCase
 {
 
     public function setFields(TestMessage $m)
@@ -338,5 +338,6 @@ class TestBase extends PHPUnit_Framework_TestCase
   // This test is to avoid the warning of no test by php unit.
   public function testNone()
   {
+      $this->assertTrue(true);
   }
 }

+ 1 - 0
php/tests/well_known_test.php

@@ -48,6 +48,7 @@ class WellKnownTest extends TestBase {
     public function testImportDescriptorProto()
     {
         $msg = new TestImportDescriptorProto();
+        $this->assertTrue(true);
     }
 
     public function testAny()

+ 17 - 38
tests.sh

@@ -302,34 +302,25 @@ generate_php_test_proto() {
 
 use_php() {
   VERSION=$1
-  PHP=`which php`
-  PHP_CONFIG=`which php-config`
-  PHPIZE=`which phpize`
-  ln -sfn "/usr/local/php-${VERSION}/bin/php" $PHP
-  ln -sfn "/usr/local/php-${VERSION}/bin/php-config" $PHP_CONFIG
-  ln -sfn "/usr/local/php-${VERSION}/bin/phpize" $PHPIZE
+  export PATH=/usr/local/php-${VERSION}/bin:$PATH
+  export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$CPLUS_INCLUDE_PATH
+  export C_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$C_INCLUDE_PATH
   generate_php_test_proto
 }
 
 use_php_zts() {
   VERSION=$1
-  PHP=`which php`
-  PHP_CONFIG=`which php-config`
-  PHPIZE=`which phpize`
-  ln -sfn "/usr/local/php-${VERSION}-zts/bin/php" $PHP
-  ln -sfn "/usr/local/php-${VERSION}-zts/bin/php-config" $PHP_CONFIG
-  ln -sfn "/usr/local/php-${VERSION}-zts/bin/phpize" $PHPIZE
+  export PATH=/usr/local/php-${VERSION}-zts/bin:$PATH
+  export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}-zts/include/php/main:/usr/local/php-${VERSION}-zts/include/php/:$CPLUS_INCLUDE_PATH
+  export C_INCLUDE_PATH=/usr/local/php-${VERSION}-zts/include/php/main:/usr/local/php-${VERSION}-zts/include/php/:$C_INCLUDE_PATH
   generate_php_test_proto
 }
 
 use_php_bc() {
   VERSION=$1
-  PHP=`which php`
-  PHP_CONFIG=`which php-config`
-  PHPIZE=`which phpize`
-  ln -sfn "/usr/local/php-${VERSION}-bc/bin/php" $PHP
-  ln -sfn "/usr/local/php-${VERSION}-bc/bin/php-config" $PHP_CONFIG
-  ln -sfn "/usr/local/php-${VERSION}-bc/bin/phpize" $PHPIZE
+  export PATH=/usr/local/php-${VERSION}-bc/bin:$PATH
+  export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}-bc/include/php/main:/usr/local/php-${VERSION}-bc/include/php/:$CPLUS_INCLUDE_PATH
+  export C_INCLUDE_PATH=/usr/local/php-${VERSION}-bc/include/php/main:/usr/local/php-${VERSION}-bc/include/php/:$C_INCLUDE_PATH
   generate_php_test_proto
 }
 
@@ -338,9 +329,8 @@ build_php5.5() {
 
   pushd php
   rm -rf vendor
-  cp -r /usr/local/vendor-5.5 vendor
-  wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
-  phpunit
+  composer update
+  ./vendor/bin/phpunit
   popd
   pushd conformance
   make test_php
@@ -349,7 +339,6 @@ build_php5.5() {
 
 build_php5.5_c() {
   use_php 5.5
-  wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
   pushd php/tests
   /bin/bash ./test.sh 5.5
   popd
@@ -361,7 +350,6 @@ build_php5.5_c() {
 
 build_php5.5_zts_c() {
   use_php_zts 5.5
-  wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 5.5-zts && cd ../..
   # TODO(teboring): Add it back
   # pushd conformance
@@ -373,9 +361,8 @@ build_php5.6() {
   use_php 5.6
   pushd php
   rm -rf vendor
-  cp -r /usr/local/vendor-5.6 vendor
-  wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
-  phpunit
+  composer update
+  ./vendor/bin/phpunit
   popd
   pushd conformance
   make test_php
@@ -384,7 +371,6 @@ build_php5.6() {
 
 build_php5.6_c() {
   use_php 5.6
-  wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 5.6 && cd ../..
   # TODO(teboring): Add it back
   # pushd conformance
@@ -394,7 +380,6 @@ build_php5.6_c() {
 
 build_php5.6_zts_c() {
   use_php_zts 5.6
-  wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 5.6-zts && cd ../..
   # TODO(teboring): Add it back
   # pushd conformance
@@ -431,9 +416,8 @@ build_php7.0() {
   use_php 7.0
   pushd php
   rm -rf vendor
-  cp -r /usr/local/vendor-7.0 vendor
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
-  phpunit
+  composer update
+  ./vendor/bin/phpunit
   popd
   pushd conformance
   make test_php
@@ -442,7 +426,6 @@ build_php7.0() {
 
 build_php7.0_c() {
   use_php 7.0
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 7.0 && cd ../..
   # TODO(teboring): Add it back
   # pushd conformance
@@ -452,7 +435,6 @@ build_php7.0_c() {
 
 build_php7.0_zts_c() {
   use_php_zts 7.0
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 7.0-zts && cd ../..
   # TODO(teboring): Add it back.
   # pushd conformance
@@ -494,9 +476,8 @@ build_php7.1() {
   use_php 7.1
   pushd php
   rm -rf vendor
-  cp -r /usr/local/vendor-7.1 vendor
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
-  phpunit
+  composer update
+  ./vendor/bin/phpunit
   popd
   pushd conformance
   make test_php
@@ -506,7 +487,6 @@ build_php7.1() {
 build_php7.1_c() {
   ENABLE_CONFORMANCE_TEST=$1
   use_php 7.1
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 7.1 && cd ../..
   if [ "$ENABLE_CONFORMANCE_TEST" = "true" ]
   then
@@ -518,7 +498,6 @@ build_php7.1_c() {
 
 build_php7.1_zts_c() {
   use_php_zts 7.1
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 7.1-zts && cd ../..
   pushd conformance
   # make test_php_c