在C:\wamp\www\study\sayHello.php的第5行中,使用了未定义的常量STDIN,被自动认定为'STDIN'。

9

我想学习php和mySQL,于是购买了一本书(php&mySql: the missing manuals 2edition)。

我在win8 64位机器上安装了Wampserver2.4。

服务器配置

Apache版本:2.4.4
PHP版本:5.4.12

在第一课时,我遇到了以下错误:

Notice: Use of undefined constant STDIN - assumed 'STDIN' in C:\wamp\www\study\sayHello.php on line 5

这是文件 "sayHello.php" 上的 PHP 代码

<?php

echo "Hello there. So I hear you're learning to be a PHP programmer!\n";
echo "Why don't you type in your name for me:\n";
$name = trim(fgets(STDIN));

echo "\nThanks, " . $name . ", it's really nice to meet you.\n\n";

?>

你的脚本中的STDIN是什么? - Suresh Kamrushi
1
你的代码在“CLI”中将能够正常工作。 - Shankar Narayana Damodaran
1
就像 Rikesh 和 Abhik 提到的,我加上了 "define('STDIN',fopen("php://stdin","r"));" 这一行代码,问题得以解决。 - user3206343
1
PHP文档提到,只有CLI SAPI定义了诸如STDIN之类的常量。 - jchook
@jchook,您能把您的评论复制到答案中,这样我们就可以点赞了吗? - AndreKR
@AndreKR 当然可以,已发布。谢谢! - jchook
9个回答

32

只需在文件顶部定义STDIN常量即可,

define('STDIN',fopen("php://stdin","r"));

这是一个 PHP 8 的问题。 - Shahid Karimi

11

当您尝试使用PHP文件运行迁移时

Artisan::call('migrate');

似乎时间也会产生这种类型的错误。为了解决这个问题,你可以简单地用下面的代码替换它:

Artisan::call('migrate', ['--force' => true ]);

如果您处于生产环境,请确保使用--force标志。


我的问题得到了确切的解决方案!谢谢! - AliN11

8

解释

CLI(命令行)SAPI定义I/O常量,如STDINSTDOUTSTDERR,纯粹是为了在该环境中方便使用。


解决方案

如其他答案所述,您可以在PHP代码中定义这些常量。您还可以使用defined()来避免在通过CLI调用时出现错误。例如:

<?php

if (!defined('STDIN')) {
  define('STDIN', fopen('php://stdin', 'r'));
}

然而,请记住在非CLI SAPI(例如Apache或FPM)中,php://stdin可能无法按照您的预期工作。例如,在通过FPM执行时访问原始POST正文,您应该使用php://input


更多信息

PHP有许多不同的SAPI(服务器应用程序编程接口),可以在各种环境中执行PHP代码,例如您的Web服务器、电子邮件服务器或命令行(CLI)。例如:

  • CGI
  • FPM
  • Milter(电子邮件过滤器)
  • Apache
  • 等等

每个SAPI可能具有略微不同的初始条件和行为。 CLI SAPI和其他SAPI之间的一些差异包括:

  • header()没有效果。
  • 某些ini设置,例如html_errorsoutput_buffering具有不同的默认值(更适合CLI)。
  • 不会将当前工作目录(CWD)更改为执行的脚本。

2
请注意,当以交互模式运行PHP(运行php)或连接到stdin的管道(运行echo Something | php)时,STDIN将不可用作常量。这可能不是立即显而易见的。 - jlh
我不得不更改define语句为:define('STDIN', fopen('php://input', 'r')); 才能让这个解决方案对我起作用。我不确定为什么,也许这取决于您使用的PHP版本。我正在使用运行在Windows上的PHP版本8.2.3,并使用Apache httpd 2.4。 - Tom Rutchik
是的,我的答案有关于 php://stdinphp://input 的注释。 - jchook

2
尝试在你的文件顶部添加以下内容:
define('STDIN',fopen("php://stdin","r"));

1
当这个错误来自于Youtube Data API code sample时,是因为该示例旨在从CLI中运行,而基于浏览器的实现不提供调用那个STDIN行所需的提示用户输入的手段。
由于认证代码作为参数提供在$authUrl变量中,在脚本第一次运行时打印到屏幕上,我通过将 $authCode = trim(fgets(STDIN)); 替换为: $authCode = $_GET['code']; 解决了我的问题。

1
对于运行Artisan命令`Artisan::call('command');`时遇到此错误的Laravel开发者,以下是解释和解决方案。
问题:
当您执行一个需要询问问题的命令时,比如使用`$this->confirm()`、`$this->anticipate()`、`$this->choice()`等方法时,就会出现此错误。问题出现在您在代码中执行命令时提问,因为它无法与提示进行交互和响应。
解决方案:
要解决这个问题,您可以修改命令以接受一个参数或选项,直接提供答案,绕过用户交互的需求。
例如,在生产环境中运行`Artisan::call('db:seed')`命令时,该命令会询问您是否真的要运行seeder,因为它处于生产环境中。您需要提供一个"yes"或"no"的回答。通过使用`--force`选项,将不会询问问题,seeder将继续运行。这只是一个例子;您的命令中可能还有其他问题,您需要实现类似的解决方案。

0
有时候你会将环境切换到生产环境并尝试在该环境下进行更新。因此最好将环境切换回本地环境。修改 .env 文件。
之前:APP_ENV=production 解决方案:APP_ENV=local

3
请分享更多细节 - 为什么改变APP_ENV可以解决给定的问题? - Nico Haase
1
我在生产环境升级数据库时遇到了错误。我把环境改回本地,并解决了该错误。 - Sangam Singh
对我来说,那看起来完全是另一个问题。此外,使用不同的环境有很好的理由 - 切换它们以尝试另一种设置是否有效似乎是解决真正问题的随机方式。 - Nico Haase
这实际上解决了我的问题。在elasticbeanstalk上运行迁移会导致尝试使用网站时出错。我改为LOCAL并运行迁移,之后一切都正常工作了。 - BlackPearl

-1

看起来你正在尝试使用一个名为STDIN的常量,但它并不存在。

STDIN用于获取与fopen当前打开的流。

$file = fopen('file/path');

$name = trim(fgets(STDIN));

在没有当前打开的流的情况下使用STDIN是无效的。

我也相信STDIN只在cli下工作,但不确定是否100%正确。如果是这种情况,请使用与上面相同的代码,但将STDIN替换为$file


-1

如果你想要使用"STDIN"常量来正确执行你的代码,你有两个选项:

# php -r "fgets(STDIN);"

或者:

# gedit file.php //make a file with <?php fgets(STDIN); ?>
# php file.php // execute the file

另一个选项:

#php
 <?php
      fgets(STDIN);
 ?>
 //click on ctrl+d

不起作用!! 您可能需要在代码中定义“STDIN”常量,如上所述。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接