PhpStorm auto include used PHP files - php

I want PhpStorm to auto-include (include_once) PHP files that I use in my respective .php file.
Simple example: MyTestClass.php:
<?php
namespace Test;
class MyTestClass
{
public function sayHello()
{
echo "hello world";
}
}
When I use this class in my index.php file, only the namespace is auto inserted:
<?php
use Test\MyTestClass;
$test = new MyTestClass();
$test->sayHello();
But this does not work in PHP. I've to include the PHP file that contains the class:
<?php
include_once('./namesapce.php');
use Test\MyTestClass;
$test = new MyTestClass();
$test->sayHello();
Is it possible that PhpStorm inserts these files automatically with the help of include_once?

Nope. PhpStorm cannot do that.
And it's extremely unlikely to be implemented.
The reason is simple: it's 2022 now and PHP has class autoloading functionality for many years (since PHP 5 which is 2004):
https://www.php.net/manual/en/language.oop5.autoload.php
https://www.php.net/manual/en/function.spl-autoload-register.php
BTW: you can use Composer autoloader for this purpose. It's fast and easy to use.
Are you using custom libraries or frameworks? If yes then quite likely you have it installed using Composer already. It's a standard tool these days for installing PHP packages (managing your dependencies) and classes autoloading.
You just need to tell where to find your classes in composer.json file and require_once the actual autoloader.
https://getcomposer.org/doc/01-basic-usage.md#autoloading

Related

Readonly in PHP 7.4

I have written a PHP library using the PHP 8.0 readonly keyword and then I realised that it would be good to support earlier versions of PHP such as 7.4.
I could easily remove the readonly keywords from my code but I don't want to do that -- they were put there for a reason!
Having a C background, I immediately thought of macros but PHP doesn't seem to have any. I've googled this answer for adding macro-like behaviour to PHP, but it looks like an overkill. And it's just for one file, and my library has 26 files at present.
Is there an easy way to make PHP 7.4 just ignore the readonly keyword and make my code cross-version? Something to the effect of this C code?
#if PHP_VERSION < 8
#define readonly /**/
#enif
Perphaps some composer build option that can pre-process files before packaging them up?
Out of the box, PHP does not include conditional compilation of the type you're hoping for.
One option would be to pre-process the source files on the fly, using a custom autoloader or Composer hook. The idea would be to let the normal code run to the point where it was going to include the file, then instead fetch its contents and manipulate it.
Note that this would not need to be a fully-functional macro system, you could just surround the code with some clear markers, like /* IF PHP 8 */ readonly /* END IF */ and match them with a simple regex pattern:
$php_code = file_get_contents($php_file_being_loaded);
if ( PHP_VERSION_ID < 80000 ) {
$php_code = preg_replace('#/\* IF PHP 8 \*/.*?/\* END IF \*/#s', '', $php_code);
}
eval($php_code);
Alternatively, you could run the pre-processing "offline", to automatically produce parallel versions of the library: one for PHP 8.0 and above, and a different one for PHP 7.4. Again, this could be as simple as the above, or you could use a tool like Rector which parses and rewrites normal PHP code (with no extra markers) according to set rules, including "downgrading" it to be compatible with a particular version of PHP.
PHP is not being compiled, therefore there's no compiler macros.
According to Backward Incompatible Changes it's a new keyword:
readonly is a keyword now. However, it still may be used as function name.
So you have two choices: a) don't re-assign it's value or b) maintain two versions.
most frameworks simply avoid using modern features for this reason alone (WordPress, Symfony, Laravel), but if you insist, your best bet is probably Composer, you can have a v1.x.x with composer.json
{
"require": {
"php": ">=7.4"
},
}
and a v2.x.x with composer.json
{
"require": {
"php": ">=8.0"
},
}
then when people do composer require lib, composer will automatically scan for and install the newest version of your library that is compatible with the local php version and composer.json-constraints (-:
the downside is that you'll have to maintain both v1 and v2 of your library for as long as you intend to support php 7.4 though..
another option is to have a loader like lib.php
if(PHP_MAJOR_VERSION >= 8){
require("lib_modern.php");
} else{
require("lib_legacy.php");
}
again with the downside of having to maintain both lib_modern and lib_legacy

How to use this QR code library (php-qrcode-detector-decoder)

Please tell me step by step, I'm amateur on php.
visit here
How to use this code.
Please help or guide me to make this code work 100%.
require __DIR__ . "/vendor/autoload.php";
$qrcode = new QrReader('path/to_image');
$text = $qrcode->text(); //return decoded text from QR Code`
QR code decoder / reader for PHP
This is a PHP library to detect and decode QR-codes.
This is first and only QR code reader that works without extensions.
Ported from ZXing library
Installation
The recommended method of installing this library is via Composer.
Run the following command from your project root:
$ composer require khanamiryan/qrcode-detector-decoder
Usage
require __DIR__ . "/vendor/autoload.php";
$qrcode = new QrReader('path/to_image');
$text = $qrcode->text(); //return decoded text from QR Code
I'm making this an answer because it is too complex for a comment.
First of all you should really try to use this code before asking for help. But let's look at the proposed code anyway:
<?php
// This line calls the autoload script generated by Composer. This ensures that you can
// just use the library classes without having to manually include their specific files
require __DIR__ . "/vendor/autoload.php";
// This instantiates the QrReader class and points it to the path of a QR code image
$qrcode = new QrReader('path/to_image');
// This calls the text method on the above instance to determine the contents of the qr code
$text = $qrcode->text();
if this doesn't work for you then you should post the error(s) you got. If you can't see any errors then add the following right below the <?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
I had a lot of trouble to get this working library without composer too.
The thing is it works on windows but not on linux because of the wrong capitalization of filenames and directories and such.
Then I found this blog that has a great solution:
https://www.mgcwebsites.co.uk/solved-class-zxinggdluminancesource-not-found/
Install a version before Composer support was added
Perhaps you use shared hosting that doesn’t allow you to install Composer or use SSH. Perhaps, like me, your server works perfectly and you want to keep it as clean as possible. Either way checking through the commits I was pleased to see Composer support is a fairly recent addition and that by downloading the last commit before Composer support was added I was able to forget about Composer and get the library working in seconds.
https://github.com/khanamiryan/php-qrcode-detector-decoder/tree/cda63b7f4a8cd84d72c41b25c74284b56dc7f2cc
It works very well now...

How to use composer/composer PHP classes to update individual packages

I want to use the composer/composer PHP classes to update individual plugin packages.
I do not want to use command-line solutions like exec("php composer.phar update");
I am unable to get it to work. I have tried several different options, much alike the following code.
It just returns a blank screen.
use Composer\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
$input = new ArrayInput(array('command' => 'require vendor/packkage dev-master'));
$output = new BufferedOutput();
$application = new Application();
$application->run($input, $output);
dd($output->fetch());
Things i would like to achieve:
Download/Update individual packages
Get result output to verify success
Dump autoload
Remove/require packages
A bit of context details:
I am creating a plugin updater for my PHP application (in admin panel).
Every plugin is a composer package and resides on my own Satis repository.
The plugins get installed into a custom dir using my composer plugin.
I can read composer.lock locally and packages.json on the satis server to figure out
what packages require updates.
update
I've managed to at least get it to work. The no-output issue was due to $application->setAutoExit that needed to be false before running. Next issue that i had was that the required package would download itself into the same directory as the class where i called it from. Solved that by using putenv and chdir. Result:
root/comp.php
putenv('COMPOSER_HOME=' . __DIR__ . '/vendor/bin/composer');
chdir(__DIR__);
root/workbench/sumvend/sumpack/src/PackageManager.php
include(base_path() . '/comp.php');
$input = new ArrayInput(array('command' => 'require', 'packages' => ['vend/pak dev-master']));
$output = new BufferedOutput();
$application = new Application();
$application->setAutoExit(false);
$application->run($input, $output); //, $output);
dd($output->fetch());
This works, but it's far from ideal.
The full solution to this would be pretty long winded, but I will try to get you on the right track.
php composer.phar require composer/composer dev-master
You can load the source of composer into your project vendors. You might have already done this.
The code you are looking for is at: Composer\Command\RequireCommand.
$install = Installer::create($io, $composer);
$install
->setVerbose($input->getOption('verbose'))
->setPreferSource($input->getOption('prefer-source'))
->setPreferDist($input->getOption('prefer-dist'))
->setDevMode($updateDevMode)
->setUpdate(true)
->setUpdateWhitelist(array_keys($requirements))
->setWhitelistDependencies($input->getOption('update-with-dependencies'));
;
$status = $install->run();
Most of the command relates to the reading and writing to of the composer.json file.
However the installer itself is independent of where the configuration actually came from. You could in theory store the configuration in a database.
This is the static create method for the installer:
public static function create(IOInterface $io, Composer $composer)
{
return new static(
$io,
$composer->getConfig(),
$composer->getPackage(),
$composer->getDownloadManager(),
$composer->getRepositoryManager(),
$composer->getLocker(),
$composer->getInstallationManager(),
$composer->getEventDispatcher(),
$composer->getAutoloadGenerator()
);
}
You will need to pay special attention to the Package, And implement your own.
Although your current attempt to run it on the command line will work, I do not recommend it because Composer is primarily a development and deployment utility, not an application utility.
In order to smoothly use it to assist with loading plugins on a production environment, you will need to tightly integrate its internals with your own application, not just use it on the side.
This is something I am interested in as well, and I think this has inspired me to look into it myself. So I'll let you know what I come up with, but this is the best I can advise you for now on what I consider to be the correct approach.

Include ZEND framework 2.3 in application without skeleton

There is a lot on the web about including ZEND, but I still don't get how to simply use it (without a skeleton) (In this case I only want to use Zend\Dom\Query)
I would like to:
1) Simply include the complete ZEND 2.3 library in a single application
or
2) Include a single ZEND 2.3 module
I'm using NGINX, but actually I just want to include it via PHP. Any hints, tips and or links?
What I did was:
include('./library/Zend/Dom/Query.php');
$c = curl_init($u);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$html = curl_exec($c);
$dom = new Zend\Dom\Query($html);
$results = $dom->execute('.foo .bar a');
...
Error is:
Fatal error: Class 'Zend_Dom_Query' not found in /SOMEDIR/myfile.php on line 12
Zend Dom and all of other Zend Framework 2 components developed independently from the framework's itself. All of them maintained separately and there are custom repositories exists for this components, respectively.
I think that the best way of using this components without framework's itself, using composer. We're living in open-source era and the year is 2014. All you need is making a search on packagist instead of trying to use Zend Dom (or any 3rd party library) via manually including/requiring into the codebase. Please use composer and follow the PSR standards.
To integrate the composer into your very own application, open the console and simply type:
cd /path/to/your/project
php -r "readfile('https://getcomposer.org/installer');" | php
After installation, use this command to add zend-dom dependency in your project:
php composer.php require zendframework/zend-dom:2.3.*
Now anywhere in your code, you can type new Zend\Dom\Query() to create a new dom query instance. (I'm assuming that you already read the autoloading process)
A simple way to include it via PHP is :
1. Make sure that the Zend directory is on your php include_path. Assuming Zend directory is in the library folder you'll have something like this in your index.php file:
$path= array();
$path[] = '.';
$path[] = './../library';
$path[] = get_include_path();
$path= implode(PATH_SEPARATOR,$path);
set_include_path($path);
2. Now just include Zend/Loader/StandardAutoloader.php first and then use it to load other classes. You can do this :
require_once 'Zend/Loader/StandardAutoloader.php';
$autoloader = new Zend\Loader\StandardAutoloader(array(
'fallback_autoloader' => true,
));
$autoloader->register();
With the $autoloader->register(), you don't need to include files each time you want to call classes. You have just to instanciate your classes :
$dom = new Zend\Dom\Query($html);

CodeIgniter and SimpleTest -- How to make my first test?

I'm used to web development using LAMP, PHP5, MySQL plus NetBeans with Xdebug.
Now I want to improve my development, by learning how to use (A) proper testing and (B) a framework. So I have set up CodeIgniter, SimpleTest and the easy Xdebug add-in for Firefox. This is great fun because maroonbytes provided me with clear instructions and a configured setup ready for download. I am standing on the shoulders of giants, and very grateful.
I've used SimpleTest a bit in the past. Here is a the kind of thing I wrote:
<?php
require_once('../simpletest/unit_tester.php');
require_once('../simpletest/reporter.php');
class TestOfMysqlTransaction extends UnitTestCase {
function testDB_ViewTable() {
$this->assertEqual(1,1); // a pseudo-test
}
}
$test = new TestOfMysqlTransaction();
$test->run(new HtmlReporter())
?>
So I hope I know what a test looks like. What I can't figure out is where and how to put a test in my new setup. I don't see any sample tests in the maroonbytes package, and Google so far has led me to posts that assume unit testing is already functionally available. What do I do?
Edit:
If you are following the maroonbytes setup, just follow the instructions:
Download the SimpleTest framework and extract the files into your #codeigniter directory.
In both your main folder and your admin/application folder create a new folder called tests.
Within the new tests folder setup additional folders called ‘models’, ‘views’, ‘controllers’, ‘libraries’ and ‘helpers’.
Any file ending in .php and with a UnitTestCase inside any of those folders, should be run. :)
First, tests must be named properly. To test a controller welcome placed in the file welcome.php a test is named welcome_controller_test.php and stored under tests/controllers/. For more, see this post.
Second, Xdebug's GET argument interferes with the test routine. See post just above, also this post.
Third, the stub test I posted needed two four lines deleted:
//require_once('../simpletest/unit_tester.php');
//require_once('../simpletest/reporter.php');
...
//$test = new TestOfMysqlTransaction();
//$test->run(new HtmlReporter())
I am making tests fairly happily now. CodeIgniter lets me create/maintain tests easily, so my goal of TDD looks reachable. My earlier attempts at TDD gave me the idea, but scratch PHP was just too barren for me to be effective (and we won't discuss VBA!).

Categories