PHP extension not built with same debug and thread safe as PHP - php

I built a number of custom PHP extensions under windows 8-10 years ago. I made the move to Ubuntu Linux for all of my web stuff some years ago and find I need to create another custom extension. I'll be doing the development under Ubuntu this time.
I've created a very simple extension (a no-op actually) just to make sure I have the build process working. It's not.
Here is what I have done:
Cloned PHP from Git
Checked out PHP-5.5
Configured with --disable-all --enable-debug --enable-maintainer-zts \
--prefix=
Build PHP
Success php -i shows:
Zend Extension Build => API220121212,TS,debug
PHP Extension Build => API20121212,TS,debug
Created ext/a1 for my new, very simple extension
Created the basic extension (from Sara Goleman's book)
Ran phpize in ext/a1
Ran ./configure --enable-a1
Ran make
Build was successful.
Copied a1.so to the extensions directory
phpdir/bin/php -dextension=a1.so -v
Fails. Results in:
Module compiled with build ID=API20121212,NTS
PHP compiled with build ID=API20121212,TS,debug
So. Color me confused. According to what I've read, the phpize command is supposed to match the extension build settings to the php build settings.
I've apparently missed something basic here somewhere.
Help will be most appreciated.

Its hard to say what exactly was going wrong, I can only say that the extension was build using a different config than the php version.
I will describe some reproducible steps how to compile a most basic extension with debug symbols within the PHP source folder. The extension contains no code except of some boilerplate code created by ext_skel. It just describes the compilation process on UNIX. It is a shell script, you might execute it.
#!/bin/sh
# Should work for all PHP5 versions
VERSION="5.6.9"
# Download the PHP source code
wget \
--continue "http://de2.php.net/get/php-$VERSION.tar.gz/from/this/mirror" \
-O "php-$VERSION".tar.gz
tar xf "php-$VERSION.tar.gz" && cd "php-$VERSION/ext"
# Create a hello extension from skeletons
./ext_skel --extname="hello"
# Uncomment two lines in ext/hello/config.m4
# Read the comments there and you'll know what I'm doing
sed -ri.original \
-e 's/(dnl )(PHP_ARG_ENABLE\(hello)/\2/' \
-e 's/(dnl )(\[ --enable-hello)/\2/' \
hello/config.m4
# Build PHP and the extension
cd ..
./buildconf --force
./configure \
--enable-debug --enable-maintainer-zts \
--enable-hello=shared
make -j
# Test if it is working
sapi/cli/php \
-dextension=modules/hello.so \
-r 'var_dump(extension_loaded("hello"));'
You can now start to enter code to ext/hello/hello.c and create your extension. If you want to compile the changes you make just issue make without arguments.
Since we've compiled using --debug we you can now use gdb to debug the C code and explore how PHP internally works. To start a debugging session use:
gdb sapi/cli/php
...
(gdb) break main
(gdb) run -dextension=modules/hello.so some.php
Of course you'll mostly set breakpoints into your extension functions rather than in the php main() function once you've added code to the extension. However, this should show the basic steps to get there.
Have fun! :)
gdb

Related

swagger-codegen or openapi-generator PHP version

The actual question: is it possible to choose the PHP version (5.6, 7.1, 7.2, ...) to generate code?
I got a swagger.json from https://api.otto.market/docs
which should be an openapi.json or so, since the file contains "openapi": "3.0.3",. Anyway ...
What i found out so far is that they (swagger and openapi-generator) seem to have templates for the code generation.
And those templates are written in the language for the version in use.
F.e. this (openapitools/openapi-generator-cli)
docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli generate \
-i /local/path/to/swagger.json \
-g php \
-o /local/path/to/generated/code/
creates a composer.json with
...
"require": {
"php": "^7.3 || ^8.0",
...
},
...
I now COULD use the templates and change the requirements.
But i think this would not be the target of a code generator.
Info about templates added to bottom.
What i guess is that there should be templates written for other PHP version.
But how would i choose them?
Are there any?
Swagger: as i read swagger came first, and openapi-generator is a fork.
So i tried swagger:
docker run --rm -v ${PWD}:/local swaggerapi/swagger-codegen-cli generate \
-i /local/path/to/swagger.json \
-l php \
-o /local/path/to/generated/code/
Swagger created code for PHP 5.5 (as of the generated composer.json).
But it brings warnings and the generated code looks "broken".
I actually do not wonder since the file is made for openapi": "3.0.3.
But what i see is: swagger has templates for PHP 5.5.
My personal current conclusion:
I can generate code real quick f.e. for an API that i do not really (have to) know.
But how does it help me if i cannot change the language version?
F.e. i need an API client in 2 projects.
One is in PHP 7.1 and the other one in 7.3. How do i solve this?
Anybody had to deal with this? Or any ideas?
INFO
templates: how to use templates:
Call docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli author template -g php -o /local/templates/
to save all templates to path templates/.
You then can f.e. copy the composer.mustache to f.e. deploy/templates/ and change it.
On generating code you use -t /local/deploy/templates to use your changed template.
Example:
docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli generate \
-i /local/path/to/swagger.json \
-g php \
-o /local/path/to/generated/code/ \
-t /local/deploy/templates
Old versions of OpenAPI Generator (e.g. 3.0.0, 4.0.0) support old PHP versions.
To easily switch between OpenAPI Generator CLI versions, you may want to use the NPM CLI wrapper for OpenAPI Generator.

Having issues creating an php extension

I try to make a custom php extension for code Encryption purposes,
I followed this tutorial to make an custom extension: How to make a PHP extension
i get this warning when compiling the extension:
WARNING
The following arguments is invalid, and therefore ignored:
--enable-php-helloworld
i did all according to the tutorial, i build on windows.
what are possible things i do wrong.
I followed that section: https://stackoverflow.com/a/32575493/3103078
I replicated the code 1:1 (Os: Windows)
used commands:
phpize
configure --enable-php-helloworld
nmake
php -d extension=php_helloworld.so --re php_helloworld
Expected result:
>>>helloworld support
Actual Result:
>>>
reproduction:
mkdir php
start https://altushost-swe.dl.sourceforge.net/project/winflexbison/win_flex_bison3-latest.zip
set path=%path%;C:\your_path\to\bison
start https://altushost-swe.dl.sourceforge.net/project/gnuwin32/sed/4.2.1/sed-4.2.1-bin.zip
set path=%path%;C:\your_path\to\sed
start https://codeload.github.com/skvadrik/re2c/zip/refs/tags/2.1.1
set path=%path%;C:\your_path\to\re2c
start https://download.microsoft.com/download/5/C/3/5C3770A3-12B4-4DB4-BAE7-99C624EB32AD/windowssdk/winsdksetup.exe
rem after install
set path=%path%;C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64
start https://windows.php.net/downloads/releases/php-devel-pack-7.3.29-Win32-VC15-x64.zip
rem install upper in php dir
phpize
configure --enable-php-helloworld
nmake
php -d extension=php_helloworld.so --re php_helloworld
The issue was not utilizing the php-src inside the sdk.
Also, on windows you need to use php-sdk-binary-tools, else it wont work when you compile it.
I'll do a tutorial on this soon.

phpize reports "Cannot find config.m4"

I am trying to run the 'phpize' command on MacOSx Mountain Lion, but this is what I get:
Cannot find config.m4.
Make sure that you run '/opt/local/bin/phpize' in the top level source directory of the module
How do I resolve this error ?
The phpize command is meant to be run at the top level of an extension source dir (this source dir should contain a file name config.m4).
See http://php.net/manual/en/install.pecl.phpize.php for more information.
In plain English, it means you're running the command from the wrong directory. You need to be in the directory that contains the source for the extension you're trying to install.
For example, if you're trying to install mcrypt, like I was when I came across this stack overflow page, you need to be in php-5.6.24/ext/mcrypt and then run the command.
My problem was that I was trying to execute the command just to see if I had it installed.
Trying to execute the command alone gives you that error, only use it inside the directory (most likely you downloaded) that contains the extension that you're trying to install.
Here some instructions to install Xdebug for php7.2 for example.
Take special care in step 3 and 4, first you change dir to the unpacked downloaded extension and then you run phpize.
http://qiita.com/MasatoYoshioka#github/items/e542f39a6f1a3bc1f71e
In terminal
ls config.m4
ls config*
config.w32 config0.m4
cp config0.m4 config.m4
cd /usr/local/src/php-5.3.29/ext/zlib
phpize
./configure
make clean && make && make install
nano php.ini
add extension=zlib.so
got inside the xdebug folder than try to run the phpize
Sometimes, using the pecl installer is not an option. This could be because you're behind a firewall, or it could be because the extension you want to install is not available as a PECL compatible package, such as unreleased extensions from git. If you need to build such an extension, you can use the lower-level build tools to perform the build manually.
The phpize command is used to prepare the build environment for a PHP extension. In the following sample, the sources for an extension are in a directory named extname:
$ cd extname
$ phpize
$ ./configure
$ make
# make install
first run ./configure it will create config.m4 file, rest the steps are same

How to set build optimization level when building PHP extension with phpize

I am writing a PHP extension in C++ using this sample.
In Visual Studio project 'properties -> c/c++ -> optimization' I can set speed optimization (O2) or Full optimization(Ox).
As I imagine, in linux after running:
phpize
./configure
Any suggestions where the optimization parameters should be set?
You can probably (I did not try, but this is how it usually goes) add additional compiler flags to the configure script when you run it. Export the flags you require first and rerun the regular compilation steps:
export CFLAGS="-O2"
# Just to make sure that the old files are removed:
phpize --clean
phpize
./configure
make
Instead of -O2 you can obviously use an other optimization level as well.

How to compile PHP to make it independend from system libraries?

I need a standalone independent-from-system-libraries version of PHP to be able to distribute it as a .zip file containing binaries. Previously the .zip was containing libxml2.so.2, libpng12.so.0, php.ini and php executable.
Recently I needed to add some functionalities and recompile the PHP. I did it with:
./configure \
--prefix=/home/user/php/out \
--libdir=. \
--enable-static=YES \
--enable-shared=NO \
--with-pdo_mysql \
--with-gd \
--with-mysql \
--enable-zip \
--enable-zend-multibyte \
--enable-cgi \
--enable-fastcgi \
--with-ldap=shared
make && make install
Then I took php from out/bin and libmysqlclient.so.16 from /usr/lib/. But the new php doesn't want to pick up the library. Once I run it I get the following error:
./php: error while loading shared libraries: libmysqlclient.so.16: cannot open shared object file: No such file or directory
libmysqlclient.so.16 and php are in the same directory. If i put libmysqlclient.so.16 to /usr/lib, php works fine.
Is there any additional option that I've forgotten about during compilation? Why isn't the "--libdir=." option working?
First, the directive is --with-libdir not --libdir. Second, I think it is relative to /usr, so putting . there means you need to put the shared libraries into /usr.
If you have done any C coding with shared libraries, you must know about ld. The easiest way to handle shared libraries path is to use ld.
You can set the library path for the current (shell) session:
bash-4.1$ export LD_LIBRARY_PATH=/path/to/your/libs
You can also configure ld to do it all the time:
bash-4.1$ echo /path/to/your/libs >> /etc/ld.so.conf
bash-4.1$ ldconfig
Maybe you could use XAMPP and save yourself sometime? It comes prepackaged and pretty portable.
http://www.apachefriends.org/en/xampp.html

Categories