PHP 8.3.0 RC 6 available for testing

highlight_file

(PHP 4, PHP 5, PHP 7, PHP 8)

highlight_file语法高亮一个文件

说明

highlight_file(string $filename, bool $return = false): string|bool

使用 PHP 内置的语法高亮器所定义的颜色,打印输出或者返回 filename 文件中语法高亮版本的代码。

许多服务器配置了自动高亮 phps 扩展的文件。比如,访问 example.phps 会显示语法高亮后的文件。添加以下一行代码到 httpd.conf 使此生效:

AddType application/x-httpd-php-source .phps

参数

filename

欲高亮文件的路径。

return

设置该参数为 true 使函数返回高亮后的代码。

返回值

如果 return 设置为 true,高亮后的代码不会被打印输出,而是以字符串的形式返回。高亮成功返回 true,否则返回 false

注释

警告

应当注意在使用 highlight_file() 时,确认没有在不经意间泄漏敏感信息,类似密码或者其他任何具有潜在安全风险的信息。

注意:

当使用了return 参数时,本函数使用其内部输出缓冲,因此不能在 ob_start() 回调函数的内部使用。

参见

add a note

User Contributed Notes 23 notes

up
12
nospam at mbeulens dot nl
14 years ago
This is my try on linenumbers
<?php
public static function highlight_file_with_line_numbers($file) {
//Strip code and first span
$code = substr(highlight_file($file, true), 36, -15);
//Split lines
$lines = explode('<br />', $code);
//Count
$lineCount = count($lines);
//Calc pad length
$padLength = strlen($lineCount);

//Re-Print the code and span again
echo "<code><span style=\"color: #000000\">";

//Loop lines
foreach($lines as $i => $line) {
//Create line number
$lineNumber = str_pad($i + 1, $padLength, '0', STR_PAD_LEFT);
//Print line
echo sprintf('<br><span style="color: #999999">%s | </span>%s', $lineNumber, $line);
}

//Close span
echo "</span></code>";
}

?>
up
4
mmcloughlin at gmail dot com
15 years ago
You can trick this function to apply additional css rules to parts of the source code.

For example, if you wanted comments to appear in bold you could do the following

<?php
ini_set
('highlight.comment', '#CCCCCC; font-weight: bold;');
highlight_file('file.php');
?>

This works because when highlight_file() writes out a comment it wraps it in <span style="color: {contents of hightlight.comment ini variable}">...</span>. Therefore as long as your ini value for highlight.comment starts with a color, you can put in whatever style declarations you like.

This applies to all of the other relavent ini values: highlight.default, highlight.html, highlight.keyword, highlight.string.
up
8
dynamicflurry [at] gmail dot com
14 years ago
Here's a great function I found to add numbers to your highlighted code:

<?php
function highlight_num($file)
{
$lines = implode(range(1, count(file($file))), '<br />');
$content = highlight_file($file, true);


echo
'
<style type="text/css">
.num {
float: left;
color: gray;
font-size: 13px;
font-family: monospace;
text-align: right;
margin-right: 6pt;
padding-right: 6pt;
border-right: 1px solid gray;}

body {margin: 0px; margin-left: 5px;}
td {vertical-align: top;}
code {white-space: nowrap;}
</style>'
;



echo
"<table><tr><td class=\"num\">\n$lines\n</td><td>\n$content\n</td></tr></table>";
}
highlight_num(__FILE__);
?>
up
3
SneakyWho_am_i
15 years ago
From W on 20 August 2008:
YES! I do it too, on many of my things! I love to be able to share my code (when I have the right to do it) with friends who aren't working on the project.

<?php

if (isset($_GET['code'])) { die(highlight_file(__FILE__, 1)); }

?>

I like to do it like this. The benefit is minimal but personally for such a small thing I would like to keep it down to one line. Maybe there is a shorter way, I don't know.. But the magic constant __FILE__ saves the day!

To access this one would be http://example.com/path/to/script.php?code
the parameter just has to be set (? or &) and you don't need the equals sign.
This way I don't generate any errors in E_ALL (because I'm likely in development), and I don't have to remember if the value was supposed to be "true" or "1" or "abacus" or whatever (I mean you're never going to specifically ask to NOT show the code, right?)

Anyway I've gone on long enough. It's nice to not be the only one who does this :D
up
2
aidan at php dot net
19 years ago
To add line numbers to source code, with optional function linking, use the below function:

http://aidanlister.com/repos/v/function.highlight_file_linenum.php

A much more thorough and smarter, though slower version is here:

http://aidanlister.com/repos/v/PHP_Highlight.php
up
1
marlon at mbwp dot nl
17 years ago
I use the folowing code to highlight a file with line numbers:

<?php
echo "<table bgcolor=#EEEEEE><tr><td width=30>";
for (
$i = 1; $i <= count(file($_GET['file'])); $i++) echo $i.".<br>";
echo
"</td><td>";
highlight_file($_GET['file']);
echo
"</td></tr></table>";
?>
up
2
afugit at imavex dot com
14 years ago
This function will not only echo out the code but will add line numbers. The extra code is for the multi-line and single-line comments using /* and */ and making sure they are highlighted appropriately. If not used, the multi-line comments will not be displayed in orange (or the default comment color).

Anthony

=============

<?php
function renderFile($filename) {
if(
file_exists($filename) && is_file($filename)) {
$code = highlight_file($filename, true);
$counter = 1;
$arr = explode('<br />', $code);
echo
'<table border="0" cellpadding="0" cellspacing="0" width="100%" style="font-family: monospace;">' . "\r\n";
foreach(
$arr as $line) {
echo
'<tr>' . "\r\n";
echo
'<td width="65px" nowrap style="color: #666;">' . $counter . ':</td>' . "\r\n";

// fix multi-line comment bug
if((strstr($line, '<span style="color: #FF8000">/*') !== false) && (strstr($line, '*/') !== false)) { // single line comment using /* */
$comments = false;
$startcolor = "orange";
}
elseif(
strstr($line, '<span style="color: #FF8000">/*') !== false) { // multi line comment using /* */
$startcolor = "orange";
$comments = true;
}
else {
// no comment marks found
$startcolor = "green";
if(
$comments) { // continuation of multi line comment
if(strstr($line, '*/') !== false) {
$comments = false;
$startcolor = "orange";
}
else {
$comments = true;
}
}
else {
// normal line
$comments = false;
$startcolor = "green";
}
}
// end fix multi-line comment bug

if($comments)
echo
'<td width="100%" nowrap style="color: orange;">' . $line . '</td>' . "\r\n";
else
echo
'<td width="100%" nowrap style="color: ' . $startcolor . ';">' . $line . '</td>' . "\r\n";

echo
'</tr>' . "\r\n";
$counter++;
}
echo
'</table>' . "\r\n";
}
else {
echo
"<p>The file <i>$filename</i> could not be opened.</p>\r\n";
return;
}
}
?>
up
2
showsource at gmail dot com
17 years ago
Please, be aware of just using marlon at mbwp dot nl example to show the sourcecode
Do as told in this manual, "CAUTION", do some check on what code to highlight.
Simply just using $_GET["file"] is very bad.
up
2
management at twilightus dot net
16 years ago
Here's a better take at highlighting a file with line numbers:

<style type="text/css">
.num {
float: left;
color: gray;
text-align: right;
margin-right: 6pt;
padding-right: 6pt;
border-right: 1px solid gray;}
</style>
<?php
function highlight_num($file)
{
echo
'<code class="num">', implode(range(1, count(file($file))), '<br />'), '</code>';
highlight_file($file);
}

highlight_num('file.php');
?>

Thanks for the implode() part from Arevos at programmingforums.org
up
1
W
15 years ago
Normally I add highlighting for files like so:

In every file that should be higlighted:
<?php
$tool_file
=$_SERVER['SCRIPT_FILENAME']; $tool_file=basename($tool_file);
include_once(
'highlight.inc.php');
showCode();
?>

And in highlight.inc.php (or your init file):
<?php
function showCode() {
if (
$_REQUEST['codeShow'] == 1) {
highlight_file($codeName);
exit ();
}
}
?>

When a user will open the sourcecode (or you'll link to it) he just adds ?codeShow=1 to the filename.
up
1
comperr dot extra at gmail dot com
15 years ago
Here is what I use
<?php

/* array() ensures that ok[] cannot have paths inserted if register globals is enabled */

$ok = array(
'f1.php',
'f2.php'
);

if (!
in_array($_GET['f'], $ok))
{
die (
'Not allowed to view this page');
}
else
{
highlight_file($_GET['f']);
}
?>
up
1
moisadoru at gmail dot com
16 years ago
A function which parses the output of highlight file and replaces &lt;span&gt; wits &lt;a&gt;, replaces the style="color: #XXXXXX" part with class="cX", storing the colors in some css rules; that way you get a smaller output size (ratio is about about 1.2 ~ 1.4):
<code>
<?php
function highlight_file2($fl,$ret){
if(!isset(
$ret)) $ret = false;
$str = highlight_file($fl,true);
preg_match_all("/\<span style=\"color: #([\d|A|B|C|D|E|F]{6})\"\>.*?\<\/span\>/",$str,$mtch);
$m = array_unique($mtch[1]);

$cls = '<style type="text/css">'."\n";
$rpl = array("</a>");
$mtc = array("</span>");
$i = 0;
foreach(
$m as $clr) {
$cls .= "a.c".$i."{color: #".$clr.";}\n";
$rpl[] = "<a class=\"c".$i++."\">";
$mtc[] = "<span style=\"color: #".$clr."\">";
}
$cls .= "</style>";
$str2 = str_replace($mtc,$rpl,$str);
if(
$ret) return $str2;
else echo
$str2;
}
?>
</code>
up
1
csst0266 at cs dot uoi dot gr
19 years ago
Here is a simple, yet useful, tip... Issuing the following command under a Unix-like OS:

ln -s your_script.php your_script.phps

Will result in the creation of a symbolic link (called your_script.phps) to the source code (your_script.php). This way you have (apart from the source code .php) the highlighted version of your script (.phps) accessible via your web browser.
up
1
venski at gmail dot com
17 years ago
I think it will be better if the variable contains the files that are allowed to be viewed. There can always befound a way to pass the name of a forbiddedn file that is not in the prohibited array.

Thus the code will be:

<?php
//array with files to allow
$allowed = array('index.php', 'menu.php', 'about.php');

// get the filename
$file = $_GET[file];
if(
file_Exists($file)){
if(
in_array($file, $allowed)){
// check if it is part of the allowed list
highlight_file($file); //highlight file
}
else{
// not allowed. just die. do not warn ;)
die("");
}
}
else{
// file doesnt exist
echo "The file does not exist.";
}
?>
up
1
cehem
1 year ago
This little code returns the file formatted as an array, line by line. You are free to choose which lines to display, and/or to add the line numbers in front of them. Index 0 = Line 1

<?php
function highlightArray($file) {
$cssRegexp = '/\<span style=\"([^\"]+)\"\>/';

# formatte le fichier complet
$highlitedFile = highlight_file($file, true);

# retire le tag <code> et <span> général
$code = substr($highlitedFile, 36, -15);

# récupère le css du <span> général
$globCss = preg_match($cssRegexp, substr($highlitedFile, 0, 36), $matche);
$globCss = $matche[1];

# découpe le fichier en array
$array = explode('<br />', $code);

$lastCss = null;
$lines = array_map(function($line) use (&$lastCss, $globCss) {
# nettoie les lignes vides
if(preg_match('/^(&nbsp;)*$/',$line)) $line = '&nbsp;';

# ajoute le dernier style ouvert s'il est stocké
if(!empty($lastCss)) $line = '<span style="'.$lastCss .'">'. $line;

# compare les ouverture et fermetures de span
$diff = substr_count($line, '<span') - substr_count($line, '</span');

# s'il y a une différence, ferme tous les span et enregistre le dernier style
if($diff > 0) {
$line .= str_repeat('</span>', $diff);
$lastCss = preg_match_all('/\<span style=\"([^\"]+)\"\>/', $line, $matches);
$lastCss = array_pop($matches[1]);
} else {
$lastCss = NULL;
}

# restaure le css général sur chaque ligne
return "<span style=\"$globCss\">$line</span>";
},
$array);

return
$lines;
}
?>
up
1
flussence at gmail dot com
2 years ago
Unfortunately the AddType trick only works for Apache *with mod_php* - FastCGI backends can't see the special content type and don't do anything special with the .phps file extension, instead trying to run it like normal code.

It's still possible to make it work using mod_rewrite trickery and a proxy script that calls highlight_file, but that's an exercise left to the reader.
up
0
rga156 at gmail dot com
7 months ago
I change all the 'style="color:#nnnnnn"' attributes to 'class="classname"' and use ini_get() to identify which names go with which colors:
<?php
$arCodes
= [
'comment' => ini_get('highlight.comment'),
'default' => ini_get('highlight.default'),
'html' => ini_get('highlight.html'),
'keyword' => ini_get('highlight.keyword'),
'string' => ini_get('highlight.string'),
];
?>
The code to do the replacement is based on the following:
<?php
$newstr
= str_replace ("<span style=\"color: $colorcode\">", "<span class=\"$classname\">", $str);
?>

To get the browser to do the work of adding line numbers, change the <br /> tags to <li> tags and add <ol> and </ol> tags:
<?php
if (false===$src = highlight_file($fpath, true) {
die (
"Unable to read file '$fpath'");
}
$NL = PHP_EOL; // To work on both Linux and Windows
// Following code assumes that styles have been replaced with classes as above
$numstr = str_replace (
[
'<code><span class="html">', "</span>$NL</code>", '<br />'],
[
'<code><ol><li><span class="html">', "</span></ol>$NL</code>", '<li>'],
$src );
?>
Then use CSS to format how you want.
For efficiency, I put all the replacement parameters into an array and do all the str_replace() actions in one pass. The class substitutions need to be first in the array in order for the <ol> replacement to work.
up
0
dev at tiagofranca dot com
1 year ago
Updating the example /manual/pt_BR/function.highlight-file.php#92697

<?php

function highlightContentOfFile(
string $file,
?
bool $showLineNumbers = true,
?
bool $insertFinalNewLine = true,
string $lineHeight = '1.1rem'
) {
$showLineNumbers = $showLineNumbers ?? true;
$insertFinalNewLine = $insertFinalNewLine ?? true;
$endLine = (int) $insertFinalNewLine;
$lineCount = count(file($file)) + $endLine;
$lines = array_reduce(range(1, $lineCount), fn ($keep, $item) => $keep .= "<li>{$item}</li>\n", '');
$content = highlight_file($file, true);

$randomInt = rand();
$style = "
<style>
table.table-code-
{$randomInt} tr td.num-{$randomInt} {
float: left;
color: gray;
font-size: 13px;
font-family: monospace;
text-align: right;
margin-right: 6pt;
padding-right: 0;
border-right: 1px solid gray;
line-height:
{$lineHeight};
background: #80808026;
font-weight: bold;
}

body {margin: 0px; margin-left: 5px;}
table.table-code-
{$randomInt} tr td {vertical-align: top;}
table.table-code-
{$randomInt} tr td code {
white-space: nowrap;
line-height:
{$lineHeight};
}

table.table-code-
{$randomInt} tr td.num-{$randomInt} ul {
margin: 0;
padding: 0.1rem 0.5rem 0.1rem 0.1rem;
list-style: none;
min-width: 2.5rem;
}
</style>
"
;

$linesContent = !$showLineNumbers ? '' : <<<"HTML"
{$style}
<td class="num-
{$randomInt}">
<ul>
$lines</ul>
</td>
HTML;

return <<<"HTML"
<table class="table-code-{$randomInt}">
<tr>
{$linesContent}
<td>
$content</td>
</tr>
</table>
HTML;
}

echo
highlightContentOfFile(__FILE__, true, true, '20px');
up
0
msn at toolskyn dot nl
17 years ago
I use this (simple and dirty) function in my tutorials to add linenumbers. I let all the linenumbers in one table cell so it is easier for people to copy and paste the code (so they don't have to remove all the linenumbers):

<?php
function highlight_with_linenum($file)
{
//open handle, set vars
$handle = fopen($file, "r");
$count = 1;
$lines = "";

//look line ends
while ($thisone = fread($handle, "1"))
{
if (
$thisone == "\n")
{
//add number
$lines .= $count . "<br />";
$count++;
}
}
//close handle
fclose($handle);

//highlight contents
$contents = highlight_file($file, TRUE);

//print output (you could as well return now)
print '<table><tr><td><code>' .
$lines . '</code></td><td>' .
$contents . '</td></tr></table>';
}
?>

Maybe it's of use to someone
up
-1
Anonymous
14 years ago
I get linenumbers this way... cause I don't like tables :p

<?php

function highlight_linenumbers ($page)
{

// remove <code> and global <span>
$code = highlight_file($page, true) ,36,-15);

echo
'<ol style="font-family:monospace; color:', ini_get('highlight.{default}') , ';">';

$arr = explode('<br />', $code);
foreach(
$arr as $line )
{
// removing newline
$line = substr($line, 0, -1);

//empty lines
if( preg_match('`^(&nbsp;)*$`',$line) ) $line = '&nbsp;';

// add colour from the previous line
if( !empty($last_colour) ) $s = '<span style="color:'.$last_colour .'">'. $s;

// Supposing we open more spans on a line than closing... let's do this properly
// We have at most one currently opened span
if( substr_count($line, '<span') - substr_count($line, '</span') > 0 )
{
$line .= '</span>';

// Grab colour to report it on next line
$last_colour = explode('<span ',$line);
$last_colour = $last_colour[count($last_colour)-1];

$last_colour = substr($last_colour,strpos($last_colour,'#'),7);

else
$last_colour = NULL;

echo
'<li>',$line,"</li>\r";
}

echo
'</ol>';
}

?>
up
-1
tony at tonybaldwin dot me
6 years ago
a practical application: http://wiki.tonybaldwin.me/doku.php/hax/misc/today
I pipe output of the old bsdcalendar script to a file with cron, on the daily, and then use this function to display "Today in History" data on a page.
up
-2
paul at cheddar dot vaughany dot com
17 years ago
It's a basic idea but one maybe worth sharing.

<?php
switch($_GET['file']) {
case
1:
highlight_file("file1.php");
break;
case
2:
highlight_file("file2.php");
break;
case
3:
highlight_file("file3.php");
break;
default:
header("Location: ".$_SERVER["PHP_SELF"]);
}
?>

Save the script as showfile.php and access it like this:

<a href="showfile.php?file=1">Click here to see file 1 source code</a>

The default case is for people editing the URL to try to access further files. Just don't add any files you don't want users to see, and maybe hard-code in large, random numbers or MD5 hashes.
up
-3
design at joelalejandro dot com dot ar
14 years ago
Just my two cents - a function that takes PHP source code from a file and decodes it to text/plain MIME-type.

Cheers,
Joel A. Villarreal Bertoldi

<?php
function phps2array($fileName)
{
return
explode("\r", html_entity_decode(strip_tags(highlight_file($fileName, true))));
}
?>

Example:
####################################

samplefile.php:
<?php
$a
= 1;

/* This is my file*/
echo $a;
?>

parser.php:
<?php
header
("Content-Type: text/plain");
print_r(parse_php_file("samplefile.php"));
?>

####################################
Results:
####################################

Array
(
[0] => <?php
[1] => $a = 1;
[
2] =>
[
3] => /* This is my file*/
[4] => echo $a;
[
5] => ?>
)

####################################
To Top