How can I autoload helper functions (outside of any class)? Can I specify in composer.json
some kind of bootstrap file that should be loaded first?
Composer/PSR - How to autoload functions?
Asked Answered
You can autoload specific files by editing your composer.json
file like this:
"autoload": {
"files": ["src/helpers.php"]
}
(thanks Kint)
Note that this file will always be included when calling the autoload file - so this better be quick, or every php script using it will be affected. –
Antipodes
This was helpful, thanks. Just as a recomendtion, check if the function exist first : if (!function_exists('myfunction')) –
Shadoof
How do I load a functions.php file containing only functions from a Git repo in a package? I have access to edit the the package's composer.json file. –
Diaphanous
@DonnieAshok Not sure what Git has to do with it. You can't load functions remotely if that's what you're asking. Just change
src/helpers.php
to path/to/functions.php
. If that's not clear, you might want to ask a new question. –
Jammiejammin This isn't a suitable answer for people who have a PSR-4 autoload pattern already set up and want to autoload functions in the same manner as classes. –
Clem
@JayBienvenu You're allowed to use this in addition to PSR-4 autoload. If that's not acceptable to you, the only other option I'm aware of is to use public static methods instead of raw functions.
__autoload
/spl_autoload_register
does not support loading functions. –
Jammiejammin I ran into a similar situation. Having a function
foobar
in a functions.php
is only possible to load via composer, if the file is outside of src
AND it uses checks, if functions already exist. If its inside src
, you will get an error like The autoloader expected class "App\functions"...
. If you dont check if your function(s) already exist, you will run into Cannot redeclare ...
issues. –
Datestamp @Datestamp That doesn't sound right.
src
isn't special, and you will only get a "Cannot declare ..." if you try loading it twice. "expected class App\functions
" is also fishy -- these aren't classes we're talking about. –
Jammiejammin Hi @mpen, i could not found a good source how to "autoload" files with composer, which contain only functions. I don't want to use classes for these. My current workaround is described in my comment above. Is there a good source how to do it "the right way"? –
Datestamp
My answer describes exactly how to do that. Just include
vendor/autoload.php
somewhere and composer will take care of the rest. It sounds like you might have a namespace (called App
) which is causing you troubles. Make sure you use the full-qualified function name if you're using one. –
Jammiejammin why "thanks Kint"? –
Ruffian
@Ruffian It's a link, click it. I learned about the feature from how they did it. –
Jammiejammin
After some tests, I have came to the conclusions that adding a namespace to a file that contains functions, and setting up composer to autoload this file seems to not load this function across all the files that require the autoload path.
To synthesize, this will autoload your function everywhere:
composer.json
"autoload": {
"files": [
"src/greetings.php"
]
}
src/greetings.php
<?php
if( ! function_exists('greetings') ) {
function greetings(string $firstname): string {
return "Howdy $firstname!";
}
}
?>
...
But this will not load your function in every require of autoload:
composer.json
"autoload": {
"files": [
"src/greetings.php"
]
}
src/greetings.php
<?php
namespace You;
if( ! function_exists('greetings') ) {
function greetings(string $firstname): string {
return "Howdy $firstname!";
}
}
?>
And you would call your function using use function ...;
like following:
example/example-1.php
<?php
require( __DIR__ . '/../vendor/autoload.php' );
use function You\greetings;
greetings('Mark'); // "Howdy Mark!"
?>
That is because your condition is incorrect - you should use FQN for
function_exists()
: if(!function_exists('You\greetings'))
. It has nothing to do with autloading. –
Landwaiter You can also use
if (! function_exists(__NAMESPACE__ . '\greetings'))
to avoid repeating the FQDN too many times, which makes it easier to move namespaces if necessary during development. –
Yves +1 for working example, also if you don't want to specify namespace before each function call just add
use function You\greetings;
to the top of you file –
Organist I have a Controller in CSDev\Controllers namespace. To use the function base_url() in app/Common.php (and in namespace CSDev) there was no way to make it work automatically (except yeah the "use function namespace\function" trick). Once I removed the namespace from Common.php, it's available directly in the Controller. –
Brumaire
© 2022 - 2024 — McMap. All rights reserved.