【问题标题】:Run composer with a PHP script in browser在浏览器中使用 PHP 脚本运行 composer
【发布时间】:2013-06-17 15:38:51
【问题描述】:

想知道是否可以使用一点 PHP 包装器从浏览器执行 composer,因为我无权访问服务器的 shell。

不确定是否可以使用 cURL 做到这一点?

【问题讨论】:

  • 您可以使用shellshell_exec,还是将命令用反引号(`) 括起来?
  • 这个应用程序位于 Rackspace 云站点...所以很遗憾我没有 shell 访问权限。

标签: php curl composer-php


【解决方案1】:

Danack 解决方案的替代方案是将"composer/composer" 作为 composer.json 中的依赖项,只需使用它的 API,而不是提取 来自composer.phar的内容。

composer.json

...
"require-dev": {
  "composer/composer": "dev-master",
}
...

手动运行composer install,这样您就可以在以下脚本中使用它:

composer_install.php

<?php
require 'vendor/autoload.php'; // require composer dependencies

use Composer\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;

// Composer\Factory::getHomeDir() method 
// needs COMPOSER_HOME environment variable set
putenv('COMPOSER_HOME=' . __DIR__ . '/vendor/bin/composer');

// call `composer install` command programmatically
$input = new ArrayInput(array('command' => 'install'));
$application = new Application();
$application->setAutoExit(false); // prevent `$application->run` method from exitting the script
$application->run($input);

echo "Done.";

当您从浏览器访问脚本时,该命令应按预期运行。

【讨论】:

  • 这个解决方案对我来说似乎是完美的,但由于一些未知的原因它不起作用。它只创建“vendor/bin/composer/.htaccess”和“vendor/bin/composer/cache”..有什么建议吗?
  • 嘿@Omranic,请在这里查看我的实际工作实现:github.com/doubleleft/hook/blob/master/src/Package/Manager.php - 它使用第二个composer.json 文件来存储附加包。因此,您需要在应用程序中要求两个供应商目录的 autoload.php
  • COMPOSER_HOME 不应指向 Composer 二进制文件。该环境变量用于设置 Composer 的 主目录,通常默认为 &lt;user&gt;/.composer。通过定义您帖子中描述的环境变量,一个名为composer 的目录将用于在/vendor/bin 目录中存储其缓存等,这不是该目录的目的。 It is not correct usage。它会起作用,但它并没有做你认为它正在做的事情。除非权限干扰,否则定义它是多余的。
  • 根据您的用例,您可能还想使用$application-&gt;setCatchExceptions(false);,以便 PHP 脚本收到任何发生异常的通知。默认情况下,如果可用,它们将呈现到 stderr,如果不可用,则呈现 PHP 输出。
  • 我以同样的方式做,但无法工作,并且没有显示错误。任何人都可以帮助我/
【解决方案2】:

是的,您可以使用一点 PHP 包装器来运行 Composer。所有 Composer 源代码都在 Phar 文件中,因此可以将其提取出来,然后您可以在设置 InputInterface 后运行它,以替换 Composer 期望通过命令行传入的命令。

如果您像这样设置目录结构:

./project  
./project/composer.json
./project/composer.lock
./project/webroot/composerExtractor.php  
./project/var/

将以下代码放入composerExtractor.php,然后从网络浏览器运行它,Composer应该将所有库下载到:

./project/vendors/

以及在该目录中生成类加载器文件。

composerExtractor.php

<?php

define('EXTRACT_DIRECTORY', "../var/extractedComposer");


if (file_exists(EXTRACT_DIRECTORY.'/vendor/autoload.php') == true) {
    echo "Extracted autoload already exists. Skipping phar extraction as presumably it's already extracted.";
}
else{
    $composerPhar = new Phar("Composer.phar");
    //php.ini setting phar.readonly must be set to 0
    $composerPhar->extractTo(EXTRACT_DIRECTORY);
}

//This requires the phar to have been extracted successfully.
require_once (EXTRACT_DIRECTORY.'/vendor/autoload.php');

//Use the Composer classes
use Composer\Console\Application;
use Composer\Command\UpdateCommand;
use Symfony\Component\Console\Input\ArrayInput;

// change out of the webroot so that the vendors file is not created in
// a place that will be visible to the intahwebz
chdir('../');

//Create the commands
$input = new ArrayInput(array('command' => 'update'));

//Create the application and run it with the commands
$application = new Application();
$application->run($input);

?>

虽然这是可能的,但这并不是一个绝妙的主意,但如果您不能使用可以让您访问 ssh 的主机,这可能是必要的。

我强烈建议至少为您自己或您的办公室获取一个静态 IP 地址,然后限制对您自己 IP 的访问,并且可能在此脚本在服务器上运行后删除它以防止它再次意外运行.

【讨论】:

  • 我正在使用这个脚本来执行composer require twig/twig,但它给了我这个错误信息:查看getcomposer.org/doc/articles/…,了解更多关于如何处理内存不足错误的信息。有没有可能在不必增加我的 php 内存限制的情况下解决这个问题(因为我认为 128M 应该足够了)
  • @Laurens 请将您的问题作为单独的问题而不是作为评论提出
【解决方案3】:

我认为在部署之前在托管源代码的机器上实际运行 Composer 会更好。

您可能会在将代码上传到主机之前从某种版本控制中签出代码(或者甚至直接将其保存在硬盘上)。那台机器应该安装 Composer 并在上传之前执行composer install。你不需要暴露生产机器来下载所有的东西。

【讨论】:

    【解决方案4】:

    我已经成功使用了这个功能。请记住,'composer-source' 是一个目录,其中包含从 composer.phar 存档中提取的内容。

    use Symfony\Component\Console\Application;
    use Symfony\Component\Console\Input\ArrayInput;
    use Symfony\Component\Console\Output\StreamOutput;
    
    function composerInstall() {
        //create composer.json with some content
        require_once 'composer-source/vendor/autoload.php';
        putenv('COMPOSER_HOME=' . __DIR__ . '/composer-source/bin/composer');
        chdir(__DIR__);
        $stream = fopen('php://temp', 'w+');
        $output = new StreamOutput($stream);
        $application = new Application();
        $application->setAutoExit(false);
        $code = $application->run(new ArrayInput(array('command' => 'install')), $output);
        return stream_get_contents($stream);
    }
    

    顺便提一下,可以在本站提取composer.phar:http://unphar.com/

    【讨论】:

      【解决方案5】:

      与 Endel 的回答类似,但我需要在数组中捕获来自 composer show --direct 的输出,因此我从作曲家存储库中的 ShowCommand 文件中提取了一些代码并制作了一个 composer-wrapper 库,我可以使用它做:

      $cw = new \shadiakiki1986\ComposerWrapper();
      $packages = $cw->showDirect();
      

      并获得一个关联数组,如['composer/composer'=&gt;'1.3.0.0']

      【讨论】:

        【解决方案6】:

        我不知道这是否总是在安装时完成,但我通过 Ubuntu 的软件包安装了 Composer,它在“/use/share/php”目录(位于包含路径中)中包含“Composer”。

        因此,只需在机器上安装 composer,我就能做到:

        require_once 'Composer/autoload.php';
        $application = new Composer\Console\Application();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-05-25
          • 2012-06-24
          • 2014-12-12
          • 1970-01-01
          • 1970-01-01
          • 2014-04-23
          • 2012-02-12
          相关资源
          最近更新 更多