PHPでコードを動的に生成し、そのコードを美しく表示したい場面はありませんか?ファイルではなく、文字列として保存されているPHPコードをハイライト表示する際に威力を発揮するのが「highlight_string関数」です。
この記事では、highlight_string関数の基本から応用まで、実践的な例を交えながら詳しく解説します。
highlight_string関数とは?
highlight_string関数は、PHP文字列の内容を構文ハイライト付きで表示するPHP標準関数です。highlight_file関数がファイルを対象とするのに対し、highlight_string関数は文字列を直接処理できる点が大きな特徴です。
基本的な構文
highlight_string(string $string, bool $return = false)
パラメータ:
$string
: ハイライト表示したいPHPコードの文字列$return
: trueの場合は結果を返す、falseの場合は直接出力(デフォルト: false)
戻り値:
$return
がtrueの場合:ハイライトされたHTMLコードを文字列で返す$return
がfalseの場合:直接HTMLを出力し、成功時はtrue、失敗時はfalseを返す
基本的な使用例
シンプルな使用方法
<?php
$code = '<?php
$message = "Hello, World!";
echo $message;
?>';
// コードをハイライト表示
highlight_string($code);
?>
この例では、$code
変数に格納されたPHPコードが構文ハイライト付きで表示されます。
結果を変数に格納する方法
<?php
$code = '<?php
function greet($name) {
return "Hello, " . $name . "!";
}
echo greet("World");
?>';
// ハイライト結果を変数に格納
$highlighted_html = highlight_string($code, true);
// 後でHTMLとして使用
echo '<div class="code-block">';
echo $highlighted_html;
echo '</div>';
?>
実践的な活用例
1. 動的コード生成とハイライト表示
<?php
function generateAndDisplayCode($className, $properties) {
$code = "<?php\nclass {$className} {\n";
foreach ($properties as $property => $type) {
$code .= " private \${$property}; // {$type}\n";
}
$code .= "\n public function __construct() {\n";
$code .= " // コンストラクタの実装\n";
$code .= " }\n";
$code .= "}\n?>";
echo "<h3>生成されたクラス: {$className}</h3>";
echo '<div style="border: 1px solid #ddd; padding: 15px; background: #f8f8f8;">';
highlight_string($code);
echo '</div>';
}
// 使用例
$properties = [
'id' => 'integer',
'name' => 'string',
'email' => 'string'
];
generateAndDisplayCode('User', $properties);
?>
2. コードスニペット管理システム
<?php
class CodeSnippetManager {
private $snippets = [];
public function addSnippet($name, $code, $description = '') {
$this->snippets[$name] = [
'code' => $code,
'description' => $description,
'created_at' => date('Y-m-d H:i:s')
];
}
public function displaySnippet($name) {
if (!isset($this->snippets[$name])) {
echo "<p>スニペット '{$name}' が見つかりません。</p>";
return false;
}
$snippet = $this->snippets[$name];
echo "<div class='snippet-container'>";
echo "<h3>{$name}</h3>";
if ($snippet['description']) {
echo "<p class='description'>{$snippet['description']}</p>";
}
echo "<div class='code-display'>";
highlight_string($snippet['code']);
echo "</div>";
echo "<small>作成日: {$snippet['created_at']}</small>";
echo "</div>";
return true;
}
public function listSnippets() {
foreach ($this->snippets as $name => $snippet) {
$this->displaySnippet($name);
echo "<hr>";
}
}
}
// 使用例
$manager = new CodeSnippetManager();
$manager->addSnippet('database_connection', '<?php
$pdo = new PDO("mysql:host=localhost;dbname=test", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
?>', 'データベース接続の基本例');
$manager->addSnippet('array_filtering', '<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$even_numbers = array_filter($numbers, function($n) {
return $n % 2 === 0;
});
print_r($even_numbers);
?>', '配列から偶数のみを抽出');
$manager->listSnippets();
?>
3. オンラインコードエディタ風の表示
<?php
function createCodeEditor($code, $title = 'Code Editor') {
$highlighted = highlight_string($code, true);
echo "<div class='code-editor'>";
echo "<div class='editor-header'>";
echo "<span class='title'>{$title}</span>";
echo "<button onclick='copyCode()'>コピー</button>";
echo "</div>";
echo "<div class='editor-content'>";
echo $highlighted;
echo "</div>";
echo "</div>";
echo "<script>
function copyCode() {
const codeText = document.querySelector('.editor-content').innerText;
navigator.clipboard.writeText(codeText).then(function() {
alert('コードがクリップボードにコピーされました!');
});
}
</script>";
echo "<style>
.code-editor {
border: 1px solid #ddd;
border-radius: 5px;
margin: 10px 0;
font-family: 'Courier New', monospace;
}
.editor-header {
background: #f0f0f0;
padding: 10px;
border-bottom: 1px solid #ddd;
display: flex;
justify-content: space-between;
align-items: center;
}
.editor-content {
padding: 15px;
background: white;
overflow-x: auto;
}
button {
padding: 5px 10px;
background: #007cba;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
}
</style>";
}
// 使用例
$sample_code = '<?php
// RESTful APIのエンドポイント例
class UserController {
public function index() {
$users = User::all();
return json_encode($users);
}
public function show($id) {
$user = User::find($id);
if (!$user) {
http_response_code(404);
return json_encode(["error" => "User not found"]);
}
return json_encode($user);
}
}
?>';
createCodeEditor($sample_code, 'UserController.php');
?>
highlight_fileとの違いと使い分け
highlight_string vs highlight_file
特徴 | highlight_string | highlight_file |
---|---|---|
入力 | 文字列 | ファイルパス |
用途 | 動的コード生成 | 既存ファイル表示 |
メモリ使用 | コードが変数に格納 | ファイルから直接読み込み |
パフォーマンス | 小さなコードに適している | 大きなファイルに適している |
使い分けの指針
<?php
// highlight_stringを使うべき場面
function showDynamicCode() {
$code = generateCodeFromDatabase();
highlight_string($code);
}
// highlight_fileを使うべき場面
function showStaticFile() {
highlight_file('existing_file.php');
}
// 両方を組み合わせた例
function showCodeComparison($file1, $dynamicCode) {
echo "<div class='comparison'>";
echo "<div class='left-panel'>";
echo "<h3>既存ファイル</h3>";
highlight_file($file1);
echo "</div>";
echo "<div class='right-panel'>";
echo "<h3>生成されたコード</h3>";
highlight_string($dynamicCode);
echo "</div>";
echo "</div>";
}
?>
高度な活用テクニック
1. コードのバリデーション付きハイライト
<?php
function validateAndHighlightCode($code) {
// 構文チェック
$tempFile = tempnam(sys_get_temp_dir(), 'php_syntax_check');
file_put_contents($tempFile, $code);
$output = [];
$return_var = 0;
exec("php -l {$tempFile} 2>&1", $output, $return_var);
unlink($tempFile);
if ($return_var === 0) {
echo "<div class='valid-code'>";
echo "<h4>✅ 構文チェック: 正常</h4>";
highlight_string($code);
echo "</div>";
} else {
echo "<div class='invalid-code'>";
echo "<h4>❌ 構文エラーが見つかりました</h4>";
echo "<pre class='error-message'>" . implode("\n", $output) . "</pre>";
echo "<h5>コード:</h5>";
highlight_string($code);
echo "</div>";
}
}
// 使用例
$valid_code = '<?php
$name = "World";
echo "Hello, " . $name;
?>';
$invalid_code = '<?php
$name = "World" // セミコロンが抜けている
echo "Hello, " . $name;
?>';
validateAndHighlightCode($valid_code);
validateAndHighlightCode($invalid_code);
?>
2. 色設定のカスタマイズ
<?php
function customHighlight($code, $theme = 'default') {
$themes = [
'default' => [
'highlight.string' => '#008000',
'highlight.comment' => '#FF8000',
'highlight.keyword' => '#0000BB',
'highlight.default' => '#000000',
'highlight.html' => '#808080'
],
'dark' => [
'highlight.string' => '#98C379',
'highlight.comment' => '#7C7C7C',
'highlight.keyword' => '#C678DD',
'highlight.default' => '#ABB2BF',
'highlight.html' => '#E06C75'
],
'ocean' => [
'highlight.string' => '#2ECC71',
'highlight.comment' => '#95A5A6',
'highlight.keyword' => '#3498DB',
'highlight.default' => '#2C3E50',
'highlight.html' => '#E74C3C'
]
];
if (isset($themes[$theme])) {
foreach ($themes[$theme] as $setting => $color) {
ini_set($setting, $color);
}
}
echo "<div class='theme-{$theme}'>";
highlight_string($code);
echo "</div>";
}
// 使用例
$sample_code = '<?php
// サンプルコード
$greeting = "Hello, World!";
echo $greeting; // 出力
?>';
echo "<h3>デフォルトテーマ</h3>";
customHighlight($sample_code, 'default');
echo "<h3>ダークテーマ</h3>";
customHighlight($sample_code, 'dark');
echo "<h3>オーシャンテーマ</h3>";
customHighlight($sample_code, 'ocean');
?>
セキュリティ上の注意点
1. 入力値の検証
<?php
function safeHighlightString($code) {
// 基本的な検証
if (empty($code)) {
echo "エラー: コードが空です。";
return false;
}
// 危険な関数の使用チェック
$dangerous_functions = ['exec', 'system', 'shell_exec', 'passthru', 'eval'];
foreach ($dangerous_functions as $func) {
if (stripos($code, $func) !== false) {
echo "警告: 危険な関数 '{$func}' が検出されました。";
echo "<details><summary>コードを表示</summary>";
highlight_string($code);
echo "</details>";
return false;
}
}
// 正常な場合のハイライト表示
highlight_string($code);
return true;
}
// 使用例
$safe_code = '<?php
$data = ["apple", "banana", "orange"];
foreach ($data as $item) {
echo $item . "\n";
}
?>';
$unsafe_code = '<?php
exec("rm -rf /"); // 危険なコード
?>';
echo "<h3>安全なコード</h3>";
safeHighlightString($safe_code);
echo "<h3>危険なコード</h3>";
safeHighlightString($unsafe_code);
?>
2. 出力のサニタイズ
<?php
function secureHighlightString($code, $allow_html = false) {
if (!$allow_html) {
// HTMLタグを除去
$code = strip_tags($code);
}
// 結果を取得してさらにサニタイズ
$highlighted = highlight_string($code, true);
// 不要な属性を削除(セキュリティ強化)
$highlighted = preg_replace('/on\w+="[^"]*"/i', '', $highlighted);
echo $highlighted;
}
?>
パフォーマンス最適化
キャッシュ機能付きハイライト
<?php
class HighlightCache {
private $cache_dir;
private $cache_lifetime;
public function __construct($cache_dir = 'cache', $cache_lifetime = 3600) {
$this->cache_dir = $cache_dir;
$this->cache_lifetime = $cache_lifetime;
if (!is_dir($cache_dir)) {
mkdir($cache_dir, 0755, true);
}
}
public function highlightString($code, $return = false) {
$cache_key = md5($code);
$cache_file = $this->cache_dir . '/' . $cache_key . '.html';
// キャッシュファイルが存在し、有効期限内の場合
if (file_exists($cache_file) &&
(time() - filemtime($cache_file)) < $this->cache_lifetime) {
$result = file_get_contents($cache_file);
} else {
// ハイライト処理を実行
$result = highlight_string($code, true);
// キャッシュに保存
file_put_contents($cache_file, $result);
}
if ($return) {
return $result;
} else {
echo $result;
return true;
}
}
}
// 使用例
$cache = new HighlightCache();
$code = '<?php
$users = [
["name" => "Alice", "age" => 25],
["name" => "Bob", "age" => 30],
["name" => "Charlie", "age" => 35]
];
foreach ($users as $user) {
echo "Name: " . $user["name"] . ", Age: " . $user["age"] . "\n";
}
?>';
// キャッシュ機能付きでハイライト表示
$cache->highlightString($code);
?>
まとめ
highlight_string関数は、PHPコードの文字列を美しく表示するための強力なツールです。静的なファイル表示に適したhighlight_file関数とは異なり、動的に生成されたコードの表示に特に有効です。
highlight_string関数の主な特徴:
- 文字列として保存されたPHPコードを直接ハイライト表示
- 動的コード生成システムとの相性が良い
- カスタマイズ可能な色設定
- セキュリティ対策が重要
適用場面:
- オンラインコードエディタ
- 動的コード生成ツール
- コードスニペット管理システム
- プログラミング学習プラットフォーム
- API ドキュメント生成
適切なセキュリティ対策とパフォーマンス最適化を行うことで、highlight_string関数は非常に有用な機能となります。ぜひあなたのプロジェクトでも活用してみてください。