最近のWebサイトのほとんどはPHPによって動的にページを生成していると思います。しかしページが生成された後はただのHTMLコードになってしまうので動的にPHPの関数を呼び出すことは困難になります。
そこでこの記事では、JavaScriptでPHPファイルの関数を呼び出す簡単な方法について説明していきます。
なお、jQueryを利用します。
サンプルコード
ここではjQueryの「Ajax」を利用します。
Ajaxは非同期にサーバーとの通信を行うためのものです。
TXTファイル
Hello!
PHP
<?php
function get_txt_content($file_name){ //テキストファイルの内容を返す関数
$file = '/home/txt/'.$file_name.'.txt'; //ファイルパス取得
$contents = file_get_contents($file); //ファイル内容取得
return $contents;
}
$func = $_POST['func'];
$argument = $_POST['argument'];
echo $func($argument);
?>
JavaScript
const file_name = "sample"; //読みだすtxtファイル名
const element = document.getElementById('txt_field');
jQuery.ajax({
type: 'post',
url: 'https://~/php/function.php', //送信先PHPファイル
data: {'func' : 'get_txt_content', 'argument': file_name }, //POSTするデータ
success: function(content){ //正常に処理が完了した時
element.innerHTML = "<p>" + content + "</p>";
}
});
HTML
<div id="txt_field"></div>
解説
これは、指定されたファイル名のテキストファイル(.txt)の内容を読み込んでドキュメント内にHTMLとして挿入するプログラムです。
PHPファイル内の関数「get_txt_content」
PHPファイル内に「get_txt_content」という関数があります。この関数は引数をファイル名として受け取り、そのファイル名のテキストファイルを開いて内容を取得し、その内容を返します。
JavaScriptからのPOST送信
JavaScriptでは、function.phpをターゲットにしてPOST送信が行われています。POSTするデータは「data:」によって指定することができ、それぞれのデータをphpファイル側は「$_POST[”]」を使って受け取ることができます。
POSTするデータのうち、‘func’ については呼び出す関数の名前であり、‘argument’ についてはその関数に渡す引数になります。
そしてそのPOST送信されたphp側では「$func( $argument )」によって直接関数を呼び出しています。
PHPからの返り値取得
この通信においては、PHPファイルが吐き出す文字列をそのまま返り値としてJavaScriptで受け取ることができます。
「success : function( content )」によって、POST通信が無事成功したときにその返り値を引数とする無名関数を実行することができます。
つまり、PHPファイル内で「echo」によって吐き出された文字列をそのまま引数にできるのです。 なお、この時PHPファイル内でエラーが発生するとエラー文まで返り値になります。
そして受け取った返り値をHTMLドキュメントの「id : txt_field」内に挿入しています。
これで、public_htmlよりも深いところにあるテキストファイルの内容等を取得することができるようになります。
注意点
しかしいくつか改善点があります。
JavaScriptからPHPにPOST通信する時、PHPファイルはpublic_html以降、つまりURLでアクセスできる位置になければいけません。
また、JavaScriptのソースコードは簡単にみられてしまうので、どこのPHPファイルにPOST送信を行っているのか悟られてしまいます。そのため、そのPHPファイルにアクセスされて思わぬ事態に発展するかもしれません。
加えて、上のソースコードだと存在しない関数を呼び出そうとしたときにエラーを発してしまいます。そこで、PHPファイルを以下のようにすると良いです。
<?php
$host = $_SERVER['HTTP_REFERER'];
$domain = parse_url($host);
if(stristr($domain['host'], "example.com")){ //example.comからのアクセスのみ
if($_POST['func'] == "get_txt_content"){
$file = '/home/txt/'.$_POST['argument'].'.txt'; //ファイルパス取得
$contents = file_get_contents($file); //ファイル内容取得
echo $contents;
}else{
echo "何も処理されませんでした";
}
}
?>
POST通信元のドメインを判定し、「example.com」でないと処理を行いません。また、関数を呼び出すのではなく、if文を使って処理を行っています。
この方法がベストなのかはよくわかりませんが、当サイトでは何回か使っています。