1

I have my own functions stored in the helpers.php file in the helpers folder relative to the composer.json file.

<?php

function config (string $params){}

function redirect() {}

In the file composer.json this file is included in autoload

"autoload": {
    "psr-4": {
      "App\\" : "./app"
    },
    "files": [
      "helpers/helpers.php"
    ],
  "scripts": {
    "delete-all-tables": "App\\Migrations\\DeleteTable::deleteAllTables",
  }
}

I used composer-dump after connecting helpers.

I am using config () at this location:

<?php

namespace App\Migrations;

use App\Components\Migration;

class DeleteTable extends Migration
{
    public static function deleteAllTables()
    {
        $param = config('db.dbname');

        $instance = new self();
        $instance->con->query("DROP DATABASE " . $param . "; CREATE DATABASE " . $param . "; USE " . $param . ";");
    }
}

When using my functions in the Migration class not through the composer, everything works correctly, but when calling scripts commands through Terminal, the config function is not executed. Then the error appears:

Fatal error: Uncaught Error: Call to undefined function App\Migrations\config() in D:\OSPanel\domains\myshop\app\Migrations\DeleteTable.php:17
Stack trace:
#0 phar://C:/composer/composer.phar/src/Composer/EventDispatcher/EventDispatcher.php(324): App\Migrations\DeleteTable::deleteAllTables(Object(Composer\Script\Event))
#1 phar://C:/composer/composer.phar/src/Composer/EventDispatcher/EventDispatcher.php(218): Composer\EventDispatcher\EventDispatcher->executeEventPhpScript('App\\Migrations\\...', 'dele
teAllTables', Object(Composer\Script\Event))
#2 phar://C:/composer/composer.phar/src/Composer/EventDispatcher/EventDispatcher.php(101): Composer\EventDispatcher\EventDispatcher->doDispatch(Object(Composer\Script\Event))
#3 phar://C:/composer/composer.phar/src/Composer/Command/ScriptAliasCommand.php(64): Composer\EventDispatcher\EventDispatcher->dispatchScript('delete-all-tabl...', true, Array)
#4 phar://C:/composer/composer.phar/vendor/symfony/console/Command/Command.php(245): Composer\Command\ScriptAliasCommand->execute(Obje in D:\OSPanel\domains\myshop\app\Migrations\Delet
eTable.php on line 11

Can you please tell me what am I doing wrong?

Are there any options for solving the problem without using helpers in the class? Thank you very much for your help!

London -
  • 13
  • 1
  • 4
  • Namespace issue, I'd say. Try `\config` at the call site. – msbit Apr 29 '21 at 16:26
  • It would help having an actual [mcve]. As a new user, please also take the [tour] and read [ask]. That said, the error message is pretty clear which function (and in which namespace!) it's trying to call. – Ulrich Eckhardt Apr 29 '21 at 17:27
  • Does this answer your question? [Composer.json Fatal error: Uncaught Error: Call to undefined function](https://stackoverflow.com/questions/67265846/composer-json-fatal-error-uncaught-error-call-to-undefined-function) – Nico Haase Apr 29 '21 at 19:40
  • @msbit , my function isn't in class, it's in the `helpers.php` file – London - May 01 '21 at 14:16
  • Yep, I believe you. Have you tried prepending the backslash, just in case? – msbit May 02 '21 at 01:10
  • Scratch that, it's not related. I'll post an answer. – msbit May 02 '21 at 01:56

1 Answers1

0

According to the Composer documentation:

Callbacks can only autoload classes from psr-0, psr-4 and classmap definitions. If a defined callback relies on functions defined outside of a class, the callback itself is responsible for loading the file containing these functions.

so any files normally included as part of a files autoloader type won't be included in this specific case.

As I see it, to get around this you have two options:

  • Move the helper functions into a helper class as static member functions and have that loaded via the Composer autoload mechanism (either psr-0 or psr-4)
  • Determine the location of the helpers.php file and require that in the migration file

For the first, it would look something like (in app/Helpers.php):

<?php

namespace App;

class Helper {
  static function config (string $params){}

  static function redirect() {}
}

which would be called thus:

\App\Helpers::config('db.dbname');

In the second, taking inspiration from 37925437, your DeleteTable.php could end up something like:

<?php

namespace App\Migrations;

use App\Components\Migration;

class DeleteTable extends Migration
{
    public static function deleteAllTables()
    {
        require(dirname(\Composer\Factory::getComposerFile()) . '/helpers/helpers.php');

        $param = config('db.dbname');

        $instance = new self();
        $instance->con->query("DROP DATABASE " . $param . "; CREATE DATABASE " . $param . "; USE " . $param . ";");
    }
}
msbit
  • 4,152
  • 2
  • 9
  • 22
  • I added this line `require(dirname(\Composer\Factory::getComposerFile()) . '/helpers/helpers.php');` to the constructor of the `Migration` class and it worked! WOW!!! Thank you very much again !! – London - May 03 '21 at 11:56