libvips / php-vips

php binding for libvips
MIT License
615 stars 25 forks source link

FFI issue #221

Closed leganz closed 9 months ago

leganz commented 1 year ago
[2023-09-20 21:49:26] productino.ERROR: Jcupitt\Vips\FFI::libraryLoad(): Return value must be of type FFI, none returned {"exception":"[object] (TypeError(code: 0): Jcupitt\\Vips\\FFI::libraryLoad(): Return value must be of type FFI, none returned at /releases/20230920214843/vendor/jcupitt/vips/src/FFI.php:230)

I am not quite sure what causes that exception.

jcupitt commented 1 year ago

Hi @leganz,

Maybe unable to find libvips? But you'd need to give a lot more information.

Xialtal commented 1 year ago

Same error. libvips setted to PATH. Tried vips-dev-w64-all-8.14.5.zip and vips-dev-w64-web-8.14.5-static.zip. Also tried to use php-vips dev-master version. Windows 10 21H2. PHP (FFI enabled):

PHP 8.1.9 (cli) (built: Aug  2 2022 14:17:26) (ZTS Visual C++ 2019 x64)
Copyright (c) The PHP Group
Zend Engine v4.1.9, Copyright (c) Zend Technologies

Error:

C:\bla-bla>php examples\bench.php test.png testNew.png

Fatal error: Uncaught TypeError: Jcupitt\Vips\FFI::libraryLoad(): Return value must be of type FFI, none returned in C:\bla-bla\vendor\jcupitt\vips\src\FFI.php:230
Stack trace:
#0 C:\bla-bla\vendor\jcupitt\vips\src\FFI.php(278): Jcupitt\Vips\FFI::libraryLoad()
#1 C:\bla-bla\vendor\jcupitt\vips\src\FFI.php(116): Jcupitt\Vips\FFI::init()
#2 C:\bla-bla\vendor\jcupitt\vips\src\Utils.php(100): Jcupitt\Vips\FFI::vips()
#3 C:\bla-bla\vendor\jcupitt\vips\src\Image.php(719): Jcupitt\Vips\Utils::filenameGetFilename()
#4 C:\bla-bla\examples\bench.php(13): Jcupitt\Vips\Image::newFromFile()
#5 {main}
  thrown in C:\bla-bla\vendor\jcupitt\vips\src\FFI.php on line 230
jcupitt commented 1 year ago

Did you see https://github.com/libvips/php-vips/issues/183#issuecomment-1402149080 ?

Xialtal commented 1 year ago

Did you see #183 (comment) ?

Yes.

duyphan2398 commented 1 year ago

I got this error before at v2.3.0, and then these checking steps worked for me.

1. Make sure that libffi is installed ( https://www.php.net/manual/en/ffi.requirements.php) 2. Make sure that ffi is installed/loaded and ffi.enable=true at php.ini

extension=ffi
[ffi]
; FFI API restriction. Possible values:
; "preload" - enabled in CLI scripts and preloaded files (default)
; "false"   - always disabled
; "true"    - always enabled
ffi.enable=true

; List of headers files to preload, wildcard patterns allowed.
;ffi.preload=

This is my Dockerfile, I think It could be for reference.

FROM alpine:latest

LABEL Maintainer="Duy Phan <duyphan2398@gmail.com>"

# Install system dependencies
RUN apk update && \
    apk upgrade &&  \
    apk add --no-cache \
    ca-certificates \
    musl-dev \
    ffmpeg \
    nano \
    bash \
    git \
    gcc \
    g++ \
    make \
    zip \
    unzip \
    curl \
    nginx \
    vips \
    vips-tools \
    vips-dev \
    glib-dev \
    libffi

# Install PHP
RUN apk update && \
    apk upgrade && \
    apk add --no-cache \
    php81 \
    php81-fpm

# Install PHP extensions
RUN apk add --no-cache \
    php81-phar \
    php81-json \
    php81-iconv \
    php81-openssl \
    php81-curl \
    php81-intl \
    php81-ftp \
    php81-xdebug \
    php81-mbstring \
    php81-soap \
    php81-gmp \
    php81-pdo_odbc \
    php81-dom \
    php81-pdo \
    php81-zip \
    php81-mysqli \
    php81-sqlite3 \
    php81-pdo_pgsql \
    php81-bcmath \
    php81-gd \
    php81-odbc \
    php81-pdo_mysql \
    php81-pdo_sqlite \
    php81-gettext \
    php81-xmlreader \
    php81-xmlwriter \
    php81-tokenizer \
    php81-bz2 \
    php81-pdo_dblib \
    php81-curl \
    php81-ctype \
    php81-session \
    php81-redis \
    php81-exif \
    php81-imap \
    php81-pspell \
    php81-tidy \
    php81-xsl \
    php81-pear \
    php81-gettext \
    php81-apcu \
    php81-simplexml \
    php81-mysqlnd \
    php81-xml \
    php81-enchant \
    php81-bcmath \
    php81-sysvsem \
    php81-opcache \
    php81-posix \
    php81-zlib \
    php81-fileinfo \
    php81-dev \
    php81-sodium \
    php81-pecl-vips \
    php81-ffi

# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer

# Remove Cache
RUN rm -rf /var/cache/apk/*
RUN rm -rf /tmp/*

# Set up initial script
COPY ./entry.sh /etc/entry.sh
RUN chmod -R 777 /etc/entry.sh
ENTRYPOINT ["sh", "/etc/entry.sh"]
jcupitt commented 1 year ago

Did you see #183 (comment) ?

Yes.

If it can't find libvips, then there must be something wrong with your PATH. Either the file is not there, or the PHP process does not have PATH set correctly.

I would add some debugging code to verify that PATH has the expected value at runtime, and that the libvips DLL is present and accessible.

uuf6429 commented 9 months ago

@jcupitt that method (loadLibrary()) could be improved. If I have time soon, I'll try to make a pull request.

I'm thinking of something like this:

    private static function libraryLoad(
        array $libraryPaths,
        string $libraryName,
        string $interface
    ): \FFI {
        ...

        new \RuntimeException(
            'Library not found in ' . implode(';', $libraryPaths),
            0,
            $e ?? null      // not sure about this, it could be useful
        );
    }

That wouldn't solve the missing library problem, but it avoids an ambiguity in code and a misdirected error message.

PS: the return null; line in libraryName is wrong (method defined as returning strings only) and redundant ('coz of the default case).

binaryfire commented 9 months ago

I've just hit the same issue after moving from our custom Ubuntu Docker image to the official PHP images. I'm using php:cli-bookworm (Debian) and have added libvips42 and enabled the ffi extension in my child image using install-php-extensions ffi .......

I know it's enabled because prior to adding it I was getting a Missing FFI extension exception. Now I'm hitting this exception:

{
  "message": "Jcupitt\\Vips\\FFI::libraryLoad(): Return value must be of type FFI, none returned",
  "exception": "TypeError",
  "file": "/workdir/vendor/jcupitt/vips/src/FFI.php",
  "line": 230,
  "trace": [
    {
      "file": "/workdir/vendor/jcupitt/vips/src/FFI.php",
      "line": 277,
      "function": "libraryLoad",
      "class": "Jcupitt\\Vips\\FFI",
      "type": "::"
    },
    {
      "file": "/workdir/vendor/jcupitt/vips/src/FFI.php",
      "line": 116,
      "function": "init",
      "class": "Jcupitt\\Vips\\FFI",
      "type": "::"
    },

Could anyone shed some light on why this is happening?

binaryfire commented 9 months ago

Never mind, just saw php-vips doesn't support preloading. Got it working by changing ffi.enable from preload to true. I guess that means the ondrej/php Ubuntu PPA sets it to true by default because I haven't had to change that before.