Functions and classes of PHP extentions in PhpStorm - php

Are functions of an extension fetch-able for an IDE like PHPStorm when they are given path to php.ini file of extension folder path? I saw that EasyPHP list functions of an extension beside it for those extension that are delivered with it, but it do not display any function for Yaf and Phalcon that is manually installed.

For Phalcon -- get yourself Phalcon Developer Tools ( http://phalconphp.com/download ) -- it contains stub files that can be used by IDE for code completion: https://github.com/phalcon/phalcon-devtools/tree/master/ide/phpstorm
For Yaf -- similar approach (stub file for usage inside IDE): https://github.com/suin/phpstorm-yaf-doc

As this frameworks are php extensions, just make sure, you have configured you php include path in IDE right.
config -> PHP -> and add there something like /usr/share/php (your location)

I use the stubs provided on packagist and install them with composer. https://packagist.org/packages/sneakybobito/phalcon-stubs
composer.json
{
"require": {
"sneakybobito/phalcon-stubs": "1.2.3"
}
}

For compiled extensions you will need a stub file which contains the name of the functions. Since recent versions of PHP include reflection capabilities for extensions[you can get the extension defined classes and functions and then reflect them to get their parameters] they should be possible to generate them.
I'm giving https://github.com/schmittjoh/php-stubs a try but the PHP svn server is down at the moment so it won't run... Will try to check back here later and update on if it works.

Related

How can I have phpstan find my custom extension class?

To implement checks for some magic _get() functions, I'm trying to implement a "class reflection extension". The manual mentions how to write the extension files themselves, and to install them by adding a service part to the neon file.
I've written an extension, and added it like so:
services:
-
class: TestClass
tags:
- phpstan.broker.methodsClassReflectionExtension
This results in the following error:
Service '0226': Class TestClass not found.
Things I've tried:
using the standalone phar
using the composer install of phpstan
using a specific namespace (PHPStan) for the extension (in the file and in the neon)
using a "random" namespace (in the file and in the neon)
Adding the file to a directory I know is being scanned for analysis
Adding the directory with the extension to the "scanDirectories" parameter
Adding the file to the "scanFiles" parameter
Adding the directory with the extension to the "paths" parameter
Adding a (deprecated) autoload directive and adding the file there.
Several of these 'adding' tries actually warn if the file is not found: if, for instance, I make a deliberate typo in one of these, lets say the autoload one, it will warn me of a missing file. But only if I don't have the service defined.
If I have the service defined and the deliberate typo in there, it returns above class-not-found (and not the typo), so I feel it's checking the extension before any of the parameters?
There seems to be a need for adding my file to a different autoloading mechanism. The question is, which and how?
I'm using
phpstan 0.12.40
php 7.2.33
The extension class needs to be loaded in runtime. You can achieve that in two ways:
Make the class available for the Composer autoloader. It's usually sufficient to configure autoload-dev section of your composer.json.
Create a file called something like phpstan-autoload.php in which you require_once the file with the extension class. And pass the path to the phpstan-autoload.php file as --autoload-file|-a option on the command line when running PHPStan.

Yocto doesn't copy libphp7.so to rootfs

To add the php apache2 module in Yocto I created a file recipes-devtools/php/php_%.bbappend with the following content:
PACKAGECONFIG = " mysql sqlite3 imap opcache openssl ${#bb.utils.filter('DISTRO_FEATURES', 'ipv6 pam', d)} apache2"
LIBS_pn-php =" -lpthread "
export LIBS
THREADS_pn-php = "pthread"
export THREADS
The module is built, but the file tmp-glibc/sysroots-components/cortexa7hf-neon-vfpv4/php/usr/lib/apache2/modules/libphp7.so is not copied to the rootfs (/usr/lib/apache2/modules/).
Why it does not deploy the file?
As temporary workaround (and to learn how to handle Yocto's path) I'm trying to manually deploy it with a ROOTFS_POSTPROCESS_COMMAND. To avoid absolute paths, what variable should I use to find out the file above under the tmp-glibc output dir? Something like:
${TMPDIR}/sysroots-components/cortexa7hf-neon-vfpv4/php/usr/lib/apache2/modules/libphp7.so
or there's something better?
In Yocto, files (which are installed in ${D} either manually in do_install or by the make, cmake, autotools, etc... in e.g. do_compile) are put in a package when they match one of the regular expression (or glob, not entirely sure about that) contained in FILES_foo.
One recipe can (and usually does) provide multiple packages. So you'd have multiple FILES_foo1 with their own paths to match.
In Yocto, the file is put in the first package where one of the paths in its FILE_foo matches the file. Even if the file matches the paths of other packages, it'll ever be in only one package, the first one.
FWIW, packages are created from leftmost to rightmost in PACKAGES variable in the recipe. By default, the PACKAGES variable is ${PN}-src ${PN}-dbg ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN} (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n292).
The default FILES_* variables are defined in bitbake.conf as well, c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf. Look for everything starting with FILES_.
In there, you can see that by default, FILES_${PN} has ${libdir}/lib*${SOLIBS} (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n296) packaged. SOLIBS is, by default, .so.* (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n280), which means only dot versions of libraries are packaged in the ${PN} package (if they are not matched by another package before).
FILES_${PN}-dev on the other hand packages ${FILES_SOLIBSDEV} which defaults to ${base_libdir}/lib*${SOLIBSDEV} ${libdir}/lib*${SOLIBSDEV}, with SOLIBSDEV in turns defaults to .so (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n313, http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n314 and http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n283).
Please note that library filenames should all start with lib to be able to be matched by the default FILES_*.
TL;DR: By default, lib*.so.* in FILES_${PN} and lib*.so in FILES_${PN}-dev.
For your specific issue, you can see that ${libdir}/apache2 directory is packaged in php-modphp thanks to FILES_${PN}-modphp (c.f. http://git.openembedded.org/meta-openembedded/tree/meta-oe/recipes-devtools/php/php.inc#n243).
So you need to add php-modphp (assuming ${PN} resolves to php) to your image to be able for the lib to be installed in your rootfs.

Attempted to load class "Memcached" from the global namespace. Did you forget a "use" statement?

I have setup existing symfony project to my local machine(windows). After composer install i get a error like this .
ClassNotFoundException in Memcached.php line 6:
Attempted to load class "Memcached" from the global namespace.
Did you forget a "use" statement?
Without detailed look into your configuration, I can only offer you a checklist with which you could give it a shot and see which part is missing.
The quesiton is tagged under symfony, so I assume that you installed a bundle. Was it leaseweb/memcache-bundle, or was some other?
Try examinging your vendor directory and try to identify if you have any of Memcached related classes.
If question to (1) is false, you may be missing some psr-4 mappings. Try examining your autoload.php and look for Memcached specific namespace.
Do you actually have php-memcached php extension installed? Have you enabled it? Try running php -m and look for php-memcached or something like that.
Please provide more info and we might be able to narrow it down.
Hope this helps.
Download the php_memcached.dll from here and place it in the ext directory. If you are using a php version older than 7.3 also download the libmemcached.dll and place it in the php root directory. Don't forget to enable extension from the php.ini file.

How to pass in options for composer?

I am trying to get this package https://github.com/nrk/predis-async and the instructions says to do: composer require predis/predis-async. I tried downloading the options phpiredis extension but when I run composer it says:
Problem 1
- predis/predis-async v0.2.3 require ext-phireids * -> the requested PHP extension phpiredis is missing from your system
Do I need to add an extension to the php ini file (if so how do I do this)?
If that doesnt work the owner the github says "pass in ['phpiredis' => false] in the array of client options" how do I pass in options with composer?
The extension phpiredis woudl need to be added to php.ini to be loaded into the PHP process if you wanted to use it.
But - according to the predis-async composer file, that ext-phpiredis module is only a suggestion - so Composer doesn't require it. However, that's only the case for the latest version of the code - the last stable release, v0.2.3 explicitly requires it - which is what you are seeing.
My suggestion it to use the latest version of the code, with
# in the 'require' part of composer
"predis/predis-async": "dev-master",
You can also explicitly list a specific sha1-hash if you didn't want the code to potentially be able change from underneath you when updating or deploying.
That latest code has moved the extension to a suggestion.
The client options are in the 'Predis\Async\Client' constructor (called by your PHP code), an array as 2nd parameter after the address of the Redis server.

How to redefine a function in php?

Now i'm stuck with file_exists() function. My project is built from repositories, one is symlinked as a DocRoot, others are available to php interpreter via include_path. But the default file_exists() cannot look at the files are placed somewhere under include_path, so i need or somehow redefine this func with a wrapper or to write my own, include it in other modules and replace all matches of this func in the directory tree. It's possible, but is not good and is not clear for developers.
I've already seen pecl-apd (2008) and pecl-runkit (2007), but there are no more such pecls among the others in my gentoo repository or the overlays. So, how to redefine a function in a modern way?
== upd ===
Ok. Let's go deeper.
Assume we have /home/me/repos/ directory, where our git modules are placed and a virtual host /var/srv/domain.com, where it all is assembled
repos_
\_site_root_
\_.git
\_file1
\_module1_
\_.git
\_we_need_this_file_too
\_module2_
\_.git
domain.com_
\_htdocs –> ~/repos/site_root
\_tmp
so we need to somehow include folders with modules 1 and 2 into the project. Then adding path to ~/repos to php include_path via vhost config
php_admin_value include_path ".:/home/me/repos"
Now php can
include ('module1/we_need_this_file_too');
from my repos directory. but when it tries to check the file before including with file_exists(), it fails, because those directories are still closed for file_exists(). This is the problem.
Now i've found a workaround with absolute paths, anyway i'd have to create a personal config in my project. I also though about to chdir() into /home/me/repos/ when it needs to (and describing <Directory> section in vhost), but it was bad idea.
From the PHP manual
PHP does not support function overloading, nor is it possible to undefine or redefine previously-declared functions.
Well, you may, as you already mentioned, if you install the runkit extension and use runkit_function_redefine or if you install APD and use override_function.
I working on library for function redefining in php5.3
Source: https://github.com/Bubujka/bu.defun
Exampls: http://defun.bubujka.org/doc.html
Simple redefining:
<?php
def('name', function(){
echo "Waserd";
});
name();
echo "\n";
def('name', function(){
echo "Bubujka";
});
name();
---
Waserd
Bubujka

Categories