質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

5回答

13266閲覧

PHPでexecコマンドが失敗する

aiueoaiueoaiue

総合スコア94

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/09/11 11:56

編集2018/09/12 09:50

###実現したい事
PHPでexecコマンドを使用してJavaを実行したいのですが、上手くいきません。

PHP

1<?php 2 exec("java Hello", $out, $rtn); 3 print_r($out); 4 echo $rtn; 5?>

このソースをコマンドライン上で実行すれば上手くいきます。しかし

PHP

1<?php 2session_start(); 3 4if(!isset($_SESSION["VARI"])){ 5 header("Location: test.php"); 6 exit; 7} 8 exec("java Hello 2>&1", $out, $rtn); 9 print_r($out); 10 echo $rtn; 11?> 12```このソースをブラウザで実行すると上手くいきません。ブラウザには$outに対応する部分がArray([0]=>sh: java:not found)と表示され、$rtnに対応する部分が127と表示されます。原因と解決策が分かる方回答お願いします。 13###補足 14PHP5.6 15ソースはすごく簡単なHelloWorldを表示させるだけのものに変更しました。 16```Java 17import java.io.*; 18 19public class Hello{ 20 public static void main(String[] args){ 21 System.out.println("HelloWorld"); 22 } 23}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2018/09/11 12:23

「こうならない」じゃなくて「どうなる」か書きましょう。
aiueoaiueoaiue

2018/09/11 12:25

本当に実行しても何も起きないんです
otn

2018/09/11 12:26

否定形で書くのをやめましょう。
otn

2018/09/11 12:27

否定形で書くのをやめましょう。情報量が皆無です。
m.ts10806

2018/09/11 23:28

質問者さん otnさんが指摘したいのは「質問するときのヒント」のこの部分です。 https://teratail.com/help/question-tips#questionTips3-4 >「○○がうまく動きません」とだけ書いても、今起きている事が伝わらなければ問題の見当がつかないのです。
m.ts10806

2018/09/11 23:29

何をしようとして、何が起きているのかは質問者さんしか知らないので、そこは具体的に記載するようにしてください。現象が伝わらないとその分、解決までが時間がかかってしまい、その分他の人の時間も浪費してしまいます。
guest

回答5

0

上のソースコードはコマンドラインからの実行、下のソースコードはwebサーバでの実行だとして。

・上と下で環境変数が違うから
・実行されるときのカレントディレクトリが違うから

ではないですか?

java実行に必要な環境変数をセットしてコマンドを実行するシェルスクリプトを作り、
それをexecしてみるとどうでしょうか。

コマンドがどういった情報を返すのか、画像をどこかに作るだけなのか、画像を返したいのかは
質問からは読み取れないので、とりあえず置いときます。

追記

私の回答1行目の仮定があっていたということですので追記します。
(質問内容を編集しておいて頂けると回答者とあとで見る人が助かります)

コマンドラインでPHPを実行する際は実行者の権限および環境で実行されますが、
webから実行される場合、実行者はwebサーバの実行権限(nobodyなど)になるので
環境変数などの環境や権限が異なります。

上と下で差異が出るのはそれが原因です。

また、下記の例の様に
execの戻り値を確認すると実行できなかった原因が推定できますので、
あらかじめそのようにすべきでしょう。

php

1<?php 2 header('Content-Type: text/plain; charset=UTF-8'); 3 4 exec("java Hello 2>&1", $output, $ret ); 5 6 print_r($output); 7 print_r($ret); 8

$retに127が返った場合は、コマンド(この場合java)が見つからなかったことを
表しているので、webサーバの実行ユーザの環境でjavaへのPATHが通って
いないということが考えられます。

対処としては
「PATHやCLASSPATHなど実行したいコマンドの実行に必要な
環境変数をセットした上で目的のコマンドを実行するようなシェルスクリプト」
を作成し、それをexecするのが一般的です。

投稿2018/09/11 12:13

編集2018/09/13 05:56
taka-saan

総合スコア665

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiueoaiueoaiue

2018/09/11 12:23

Javaは/home/ユーザ名にある画像を/home/ユーザ名/sampleディレクトリに作るというものです。
taka-saan

2018/09/11 12:30

それだと、上記に加えて /home/ユーザ名/sample への apache実行ユーザによる 書き込み許可も必要になります。 いずれにしてもシェル化は必要かと。
aiueoaiueoaiue

2018/09/11 12:42

java実行に必要な環境変数ってCLASSPATHくらいしか知らないんですけど、それくらいでいいんでしょうか?
taka-saan

2018/09/12 00:58

そのまえに「上のソースコードはコマンドラインからの実行、下のソースコードはwebサーバでの実行だとして。」のエスパーが当たってたかどうか教えてください。 次に、exec()の第2引数を指定して何が返却されているか確認し、それに基づいた対策を検討してみてください。
aiueoaiueoaiue

2018/09/12 04:41

エスパーは当たってます。第2引数はechoでブラウザに表示させてみると、Array()が表示されました。
taka-saan

2018/09/12 07:26

第2引数は配列です。PHPで配列の中身を全て表示する際は、print_r()が便利です。
aiueoaiueoaiue

2018/09/12 08:14

print_r()にしても同じArray()が表示されました。第3引数はechoで127と表示されました。
aiueoaiueoaiue

2018/09/12 10:20

パスを通しても変化がないので一旦仕切り直します。
taka-saan

2018/09/12 10:30

どうやって「パスを通し」たんですかね。。。
aiueoaiueoaiue

2018/09/12 10:32

set path=($HOME/local/bin /sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin $HOME/bin /usr/local/openjdk8/bin) setenv JAVA_HOME /usr/local/share/licenses/openjdk8-8.181.13で通しました。
taka-saan

2018/09/12 10:35

それをご自身のシェルで実行しても無駄ですが、シェルスクリプトで試していらっしゃらないのですか?
aiueoaiueoaiue

2018/09/12 10:38

まずシェルスクリプトがよくわからないんでパスを通して上手くいったらシェルスクリプトに挑戦しようかなって考えてます。
taka-saan

2018/09/12 10:42

対処としてはPATHやCLASSPATHなど実行したいコマンドの実行に必要な 環境変数をセットした上で目的のコマンドを実行するようなシェルスクリプトを作成し、 それをexecしないとだめです。挑戦してください。 私からの回答は以上とさせて頂きます。
aiueoaiueoaiue

2018/09/12 10:48

環境変数のセットはシェルスクリプトに含まず、javaの実行コマンドだけシェルスクリプトにするって解釈でいいんですよね?
guest

0

exec("java Hello"); によって出力される画像は、
HTTPプロトコルに則った応答になっているでしょうか。

もしもPNG画像を出力するものだとした場合、
Content-type: image/png;
みたいなヘッダーを伴って出力されるべきですが、
おそらく察するに、
その手のヘッダー類を適切に処理していない気がします。

そして
session_start();
の場面においてセッションに関わるヘッダーがすでに出力されてしまっていて、
htmlが続かなければならない場面なのに画像データを送っても
webブラウザは適切に処理できていないのかもしれません。
あるいは、
$_SESSION["VARI"]が定義されていない場合は、
exit(); で処理が抜けてしまいます。
画像は出力されませんよね。

先の方のソースでうまく行っているのは、
全くヘッダー類を送信していないから、
webブラウザが送られてきたデータを解析して画像だなと判断して
表示しているに過ぎません。
webブラウザが賢いから表示できたというだけで。

投稿2018/09/11 12:05

編集2018/09/11 12:06
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiueoaiueoaiue

2018/09/11 12:20 編集

header("Content-type: image/png");を追加してブラウザで実行してみると、PHPが壊れているため表示できませんでした。と表示されて、何も表示されなくなりました。 echoで確認してみたところ$_SESSION["VARI"]はちゃんと受け渡されていました。
退会済みユーザー

退会済みユーザー

2018/09/11 12:46

PHPが壊れている? phpの文法チェックで記述ミスが見つかるかもしれませんよ。 ちなみに、exec("java Hello"); の実行結果は生のママ画像データを出力するものですか? 仮にreadfile("実画像ファイルのおいてある場所"); などとした場合はどうなりますか?
m.ts10806

2018/09/12 00:56

画像が出来上がるだけでその画像を出力するコードではないからではないでしょうか。 実行して画像を出力したければ、出来上がった画像のパスをPHP側で指定してリソースを読み込んで「出力」する処理が必要かと。ただ、きちんとexec()で実行を待つ(正確には画像が出来上がるのを待つ)ようにしないと結果は同じかもしれません。 いずれにしてもHelloというプログラムの提示がないと再現確認できないのでこれ以上は回答難しそうですね。
guest

0

第2,第3引数を使って結果を確認してみてください。

output

引数 output が存在する場合、指定した配列は、 コマンドからの出力の各行で埋められます。 \n のような後に続く空白は、この配列には含まれません。 配列に既に何らかの要素が 含まれる場合は、exec() は配列の最後に追加される ことに注意してください。関数が要素を追加することを望まないのなら、 それが exec() に渡される前に、配列の unset() を呼び出してください。

return_var
引数return_varが、引数 output と共に存在する場合、実行したコマンドの ステータスがこの変数に書かれます。

プログラムは指示した通りにしか動きません。
「何も起きない」のであれば、きちんと結果を受け取って「何かを起こす」ように作るのが、作る側の責任です。
大体の機能には実行結果(return)があります。true/falseだけであっても受け取っておくに越したことはありません。幸いこの関数はステータスコードを返してくれるので原因究明はしやすいですよ。

「php exec 使い方」で調べれば第2、第3引数を効果的に使うような使い方をしている記事も出てくるのでそちらを参考にしてください。

投稿2018/09/11 23:26

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

if文の中に入ってexitしてるんじゃないんですか?
セッションの中身を確認してみては?

投稿2018/09/11 12:03

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiueoaiueoaiue

2018/09/11 12:26

if文の下にechoを作って確認してみましたが、exitはしてませんでした。
guest

0

たまたま、同じ悩みで検索しているときにぶつかりました。
さすがに回答が遅すぎて見てはいただけないかもしれませんが・・・

もしnot foundが問題なら・・・
※ 前提部分のexecも実行できないのなら、ほかの方法が必要かと・・・
引数はいったん省いていますので必要に応じて・・

// ==========================
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$java_exec = exec('where java');
} else {
$java_exec = exec('which java');
}
exec($java_exec.' Hello');
// ==========================
はいかがでしょう?

投稿2021/02/22 22:42

YmamandaRentaro

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問