Skip to content

Instantly share code, notes, and snippets.

@masakielastic
Last active June 17, 2025 21:57
Show Gist options
  • Select an option

  • Save masakielastic/7d7bec152c566a4bc3ee61a373baf357 to your computer and use it in GitHub Desktop.

Select an option

Save masakielastic/7d7bec152c566a4bc3ee61a373baf357 to your computer and use it in GitHub Desktop.
PHP スクリプトを実行する C 言語のプログラム

PHP スクリプトを実行する C 言語のプログラム

ビルド

make manual

もしくは

gcc -Wall -std=gnu99 -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L \
    -I/usr/include/php/20240924 \
    -I/usr/include/php/20240924/main \
    -I/usr/include/php/20240924/TSRM \
    -I/usr/include/php/20240924/Zend \
    -I/usr/include/php/20240924/ext \
    -I/usr/include/php/20240924/ext/date/lib \
    -o php_embed php_embed.c \
    -lphp8.4

実行

./php_embed
# Makefile for PHP embedded program
# プログラム名
TARGET = php_embed
# ソースファイル
SOURCES = php_embed.c
# PHP設定の取得
PHP_CONFIG = php-config8.4
# 個別に設定を取得
PHP_INCLUDES = $(shell $(PHP_CONFIG) --includes 2>/dev/null)
PHP_LDFLAGS = $(shell $(PHP_CONFIG) --ldflags 2>/dev/null)
PHP_LIBS = $(shell $(PHP_CONFIG) --libs 2>/dev/null)
# 埋め込み用ライブラリの取得(複数の方法を試す)
PHP_EMBED_LIBS = $(shell $(PHP_CONFIG) --embed 2>/dev/null || echo "-lphp8.4")
# 手動でのフラグ設定(php-configが正しく動作しない場合)
MANUAL_INCLUDES = -I/usr/include/php/20240924 -I/usr/include/php/20240924/main -I/usr/include/php/20240924/TSRM -I/usr/include/php/20240924/Zend -I/usr/include/php/20240924/ext -I/usr/include/php/20240924/ext/date/lib
MANUAL_LIBS = -lphp8.4
# コンパイラ設定
CC = gcc
CFLAGS = -Wall -std=gnu99 $(if $(PHP_INCLUDES),$(PHP_INCLUDES),$(MANUAL_INCLUDES)) -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L
LDFLAGS = $(PHP_LDFLAGS)
LIBS = $(if $(PHP_LIBS),$(PHP_LIBS) $(PHP_EMBED_LIBS),$(MANUAL_LIBS))
# デフォルトターゲット
all: $(TARGET)
# メインターゲット
$(TARGET): $(SOURCES)
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCES) $(LDFLAGS) $(LIBS)
# クリーンアップ
clean:
rm -f $(TARGET) test.php
# インストール(オプション)
install: $(TARGET)
cp $(TARGET) /usr/local/bin/
# アンインストール(オプション)
uninstall:
rm -f /usr/local/bin/$(TARGET)
# デバッグビルド
debug: CFLAGS += -g -DDEBUG
debug: $(TARGET)
# テスト実行
test: $(TARGET)
./$(TARGET)
# PHP設定の確認
phpinfo:
@echo "PHP Config: $(PHP_CONFIG)"
@echo "Checking php-config8.4..."
@$(PHP_CONFIG) --version 2>/dev/null || echo "php-config8.4 not found"
@echo "PHP Includes: $(PHP_INCLUDES)"
@echo "PHP LDFLAGS: $(PHP_LDFLAGS)"
@echo "PHP LIBS: $(PHP_LIBS)"
@echo "PHP EMBED LIBS: $(PHP_EMBED_LIBS)"
@echo ""
@echo "Manual settings:"
@echo "MANUAL_INCLUDES: $(MANUAL_INCLUDES)"
@echo "MANUAL_LIBS: $(MANUAL_LIBS)"
# 手動コンパイル(php-configが使えない場合)
manual: $(SOURCES)
$(CC) -Wall -std=gnu99 -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L $(MANUAL_INCLUDES) -o $(TARGET) $(SOURCES) $(MANUAL_LIBS)
# pkg-configを使った方法
pkgconfig: $(SOURCES)
$(CC) -Wall -std=c99 `pkg-config --cflags php8.4` -o $(TARGET) $(SOURCES) `pkg-config --libs php8.4`
.PHONY: all clean install uninstall debug test phpinfo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <strings.h>
#include <sapi/embed/php_embed.h>
int execute_php_code(const char *code, const char *description) {
printf("実行中: %s\n", description);
int result = 0;
zend_first_try {
if (zend_eval_string((char*)code, NULL, description) == SUCCESS) {
printf("✓ %s の実行が成功しました\n", description);
result = 1;
} else {
printf("✗ %s の実行に失敗しました\n", description);
if (PG(last_error_message) && ZSTR_LEN(PG(last_error_message)) > 0) {
printf(" エラー: %s\n", ZSTR_VAL(PG(last_error_message)));
}
}
} zend_catch {
printf("✗ %s で例外が発生しました\n", description);
result = 0;
} zend_end_try();
return result;
}
int execute_php_file(const char *filename) {
printf("ファイル実行中: %s\n", filename);
int result = 0;
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle, filename);
zend_first_try {
if (zend_execute_scripts(ZEND_REQUIRE, NULL, 1, &file_handle) == SUCCESS) {
printf("✓ ファイル %s の実行が成功しました\n", filename);
result = 1;
} else {
printf("✗ ファイル %s の実行に失敗しました\n", filename);
}
} zend_catch {
printf("✗ ファイル %s の実行で例外が発生しました\n", filename);
result = 0;
} zend_end_try();
zend_destroy_file_handle(&file_handle);
return result;
}
int main(int argc, char *argv[])
{
printf("=== PHP埋め込み実行プログラム (最終版) ===\n");
printf("PHP Version: %s\n", PHP_VERSION);
// PHPの初期化
if (php_embed_init(argc, argv) != SUCCESS) {
fprintf(stderr, "エラー: PHPの初期化に失敗しました\n");
return 1;
}
printf("✓ PHP埋め込みSAPIの初期化が成功しました\n");
// リクエスト開始
if (php_request_startup() == FAILURE) {
fprintf(stderr, "エラー: リクエスト開始に失敗しました\n");
php_embed_shutdown();
return 1;
}
printf("✓ PHPリクエストの開始が成功しました\n");
// エラー表示を有効にする
PG(display_errors) = 1;
EG(error_reporting) = E_ALL;
printf("\n=== PHPコード実行テスト ===\n");
// 基本的なecho文
execute_php_code("echo 'Hello from embedded PHP!' . \"\\n\";", "基本echo文");
// 変数と演算
execute_php_code("$a = 10; $b = 20; echo 'Result: ' . ($a + $b) . \"\\n\";", "変数と演算");
// 配列操作
execute_php_code("$arr = [1, 2, 3, 4, 5]; echo 'Array sum: ' . array_sum($arr) . \"\\n\";", "配列操作");
// 文字列操作
execute_php_code("$str = 'Hello World'; echo 'Length: ' . strlen($str) . \"\\n\"; echo 'Uppercase: ' . strtoupper($str) . \"\\n\";", "文字列操作");
// 条件分岐
execute_php_code("$x = 15; if ($x > 10) { echo 'x is greater than 10' . \"\\n\"; } else { echo 'x is not greater than 10' . \"\\n\"; }", "条件分岐");
// ループ
execute_php_code("for ($i = 1; $i <= 3; $i++) { echo 'Count: ' . $i . \"\\n\"; }", "forループ");
// 関数定義と呼び出し
execute_php_code("function greet($name) { return 'Hello, ' . $name . '!'; } echo greet('PHP') . \"\\n\";", "関数定義・呼び出し");
// 日付・時刻
execute_php_code("echo 'Current time: ' . date('Y-m-d H:i:s') . \"\\n\";", "日付・時刻");
// コマンドライン引数のファイル実行
if (argc > 1) {
printf("\n=== ファイル実行 ===\n");
execute_php_file(argv[1]);
} else {
printf("\n=== サンプルファイル作成・実行 ===\n");
// サンプルPHPファイルを作成
FILE *fp = fopen("sample.php", "w");
if (fp) {
fprintf(fp, "<?php\n");
fprintf(fp, "echo \"=== Sample PHP File ===\\n\";\n");
fprintf(fp, "$data = ['apple', 'banana', 'orange'];\n");
fprintf(fp, "foreach ($data as $index => $fruit) {\n");
fprintf(fp, " echo ($index + 1) . \". $fruit\\n\";\n");
fprintf(fp, "}\n");
fprintf(fp, "echo \"Total items: \" . count($data) . \"\\n\";\n");
fprintf(fp, "?>");
fclose(fp);
printf("sample.phpを作成しました\n");
execute_php_file("sample.php");
remove("sample.php");
}
}
// 出力フラッシュ
printf("\n=== 出力フラッシュ ===\n");
fflush(stdout);
php_output_flush_all();
printf("✓ 出力フラッシュが完了しました\n");
// クリーンアップ
printf("\n=== クリーンアップ ===\n");
php_embed_shutdown();
printf("✓ プログラム終了\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment