PHP Pre-Processing with XMake: XMake Internals |
>> << PHP Language XMExtension included source: phpc.inc |
<?php
/*
These functions support the phpc XMExtension
This file is automatically included by XMake when processing .phpc files
You may include this file in ordinary .php scripts to use the error handling in a command line or a web server context:
$success=include_once( getenv("XMAKE_HOME")."/config/XMExtensions/phpc.inc" );
if (!$success) {
trigger_error("Failed including phpc.ini",E_USER_ERROR);
}
// set the custom error handler
$old_handler = set_error_handler("phpc_error_handler");
*/
// optionally, read a file specified in XMake.conf to simulate a web server environment
$XMAKE_EXT_PHPC_GLOBAL_INC=getenv("XMAKE_EXT_PHPC_GLOBAL_INC");
if (!empty($XMAKE_EXT_PHPC_GLOBAL_INC)){
phpc_require_once($XMAKE_EXT_PHPC_GLOBAL_INC);
}
// phpc_add_prerequisites() talks to phpc_get_prerequisites() with global:
$GLOBALS["XMAKE_PHP_PREREQUISITE_FILES"]=array();
// useful for embedding dynamic php:
define('PHP_OPEN_TAG','<'.'?php ');
define('PHP_CLOSE_TAG','?'.'>');
$phpc_error_codes[E_USER_ERROR]="E_USER_ERROR";
$phpc_error_codes[E_WARNING]="E_WARNING";
$phpc_error_codes[E_USER_WARNING]="E_USER_WARNING";
$phpc_error_codes[E_NOTICE]="E_NOTICE";
$phpc_error_codes[E_USER_NOTICE]="E_USER_NOTICE";
// display_errors causes error display on STDOUT
$phpc_display_errors=(bool) ini_get('display_errors');
// log_errors writes errors to STDERR, or error_log, if set
// log_errors is independent of display_errors
$phpc_log_errors=(bool) ini_get('log_errors');
// for compatibility with earlier versions of PHP CLI:
if (empty($_SERVER["REQUEST_METHOD"])){
// we are not running on a web server
$phpc_server_env = false;
} else {
// we are running on a web server
// NOTE: user 'nobody' usually doesn't have permission to open STDERR
$phpc_server_env = true;
$phpc_break_str="<br \>";
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// FILE DEPENDENCY TRACKING FUNCTIONS
/*
USAGE: sample code for .phpc file
// suppose you want to use 'file1' in the same directory as this script:
// a) create absolute path to it
$prerequisite_file=dirname(__FILE__).'/file1';
// register it:
phpc_add_prerequisites( $prerequisite_file );
NOTE:
Paths to files must be ABSOLUTE paths, resolving any symbolic links
assume your script uses a file 'file1', in the same directory as the script file
$file1=realpath(file1) doesn't work since it returns false if the file doesn't exist
since file1 may be created by XMake, we need the path whether or not it exists
__FILE__ is always the full path to the current file
*/
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/// phpc_add_prerequisites
/**
* @desc add prerequisite files to global array
accepts a single filename string or array of filenames as input
accepts relative paths or absolute
if $prerequisiteFiles is not not an absolute path:
create an absolute path, relative to current directory
* @param mixed $prerequisiteFiles
* @return void
*/
function phpc_add_prerequisites( $prerequisiteFiles ){
global $XMAKE_PHP_PREREQUISITE_FILES;
if (!is_array($prerequisiteFiles)){
$prerequisiteFiles=array($prerequisiteFiles);
}
foreach ( $prerequisiteFiles as $i => $file ){
$prerequisiteFiles[$i]=phpc_absPath($file);
}
$XMAKE_PHP_PREREQUISITE_FILES = array_merge($XMAKE_PHP_PREREQUISITE_FILES,$prerequisiteFiles);
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/// phpc_get_prerequisites
/**
* @desc returns $XMAKE_PHP_PREREQUISITE_FILES, removing any duplicate values
used by phpc.mkh: XME_phpc_dependCmd
called with: php -r '... phpc_get_prerequisites(); ...'
*
* @return array
*/
function phpc_get_prerequisites(){
global $XMAKE_PHP_PREREQUISITE_FILES;
$prerequisiteFiles = array_merge(get_included_files(), $XMAKE_PHP_PREREQUISITE_FILES);
$prerequisiteFiles = array_unique ( $prerequisiteFiles );
return $prerequisiteFiles;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// ERROR HANDLING FUNCTIONS
/*
The custom error handler, phpc_error_handler is automatically installed
*/
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/// _phpc_write_error
/**
* @desc If running in CLI environment or log_errors=1
send errors to STDERR
If running on a web server and log_errors=0:
format as HTML and write to STDOUT
*
* @return void
*/
function _phpc_write_error( $string ){
global $phpc_log_errors;
global $phpc_display_errors;
global $phpc_server_env;
global $phpc_break_str;
if ( $phpc_display_errors ){
if ($phpc_server_env){
// if running on a web server, format as HTML
$text = htmlspecialchars($string);
$text = str_replace("\n", $phpc_break_str."\n", $text );
echo($text);
} else {
echo($string);
}
}
if ( $phpc_log_errors ){
// never format as HTML
// if error_log is empty, error_log() writes to STDERR and date/time is not prepended
error_log($string);
}
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/// phpc_error_handler
/**
* @desc error handler function
*
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param string $errline
* @return void
*/
function phpc_error_handler ($errno, $errstr, $errfile, $errline) {
global $XMAKE_XME_PHPC_FATAL_ERROR_MASK;
global $phpc_error_codes;
$debug=false;
$error_message = "";
// if we are being called by a wrapper (such as phpc_lintCmd) then don't overwrite:
if (!isset($XMAKE_XME_PHPC_FATAL_ERROR_MASK)){
$XMAKE_XME_PHPC_FATAL_ERROR_MASK=(int)getenv("XMAKE_XME_PHPC_FATAL_ERROR_MASK");
}
// handle all allowable errors:
if ($debug ) _phpc_write_error( " XMAKE_XME_PHPC_FATAL_ERROR_MASK=$XMAKE_XME_PHPC_FATAL_ERROR_MASK\n");
if ( ($errno & error_reporting()) ||
($errno & $XMAKE_XME_PHPC_FATAL_ERROR_MASK)
) {
if ($debug) $error_message = "phpc_error_handler: ";
if (array_key_exists($errno,$phpc_error_codes)) {
$error_code = $phpc_error_codes[$errno];
} else {
$error_code = "Unkown error type";
}
$error_message .="PHP: ";
$error_message .=$error_code." [$errno] $errstr";
$error_message .=" on line ".$errline.", ".$errfile;
if ($debug && ($errno & $XMAKE_XME_PHPC_FATAL_ERROR_MASK) ){
$error_message .=" FATAL ERROR aborting...";
}
_phpc_write_error( $error_message."\n" );
}
// now handle exit status
if ($errno & $XMAKE_XME_PHPC_FATAL_ERROR_MASK ){
exit(1);
}
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/// phpc_fatal_error_mask
/**
* @desc error handler function
similar to error_reporting()
optionally set mask for fatal errors, return current mask
normally, $XMAKE_XME_PHPC_FATAL_ERROR_MASK cannot be set if it is already:
when running as CLI SAPI, 'xmake phpc.lint' and XME_phpc_dependCmd controlfatal errors
override this behavior by using $force=true
In web server mode, $XMAKE_XME_PHPC_FATAL_ERROR_MASK is always set, regardless
*
* @param int $error_mask
* @param boolean $force
* @return int
*/
function phpc_fatal_error_mask ($error_mask=NULL, $force=false) {
global $XMAKE_XME_PHPC_FATAL_ERROR_MASK;
if ( $error_mask==NULL ) return $XMAKE_XME_PHPC_FATAL_ERROR_MASK;
if (!isset($XMAKE_XME_PHPC_FATAL_ERROR_MASK)){
$XMAKE_XME_PHPC_FATAL_ERROR_MASK=(int)getenv("XMAKE_XME_PHPC_FATAL_ERROR_MASK");
}
if (!isset($XMAKE_XME_PHPC_FATAL_ERROR_MASK) || $force==true || !empty($_SERVER["REQUEST_METHOD"])){
$XMAKE_XME_PHPC_FATAL_ERROR_MASK=$error_mask;
}
return $XMAKE_XME_PHPC_FATAL_ERROR_MASK;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// UTILITY FUNCTIONS
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/// phpc_absPath
/**
* @desc return an absolute path to a file:
if $path is absolute, resolve any aliases, etc.;
if $path is relative, create absolute path from $relPathDir
*
* @param string $path
* @param string $relPathDir
* @return string
*/
function phpc_absPath($path, $relPathDir=""){
if ( $path{0} != '/' ){
if ( empty($relPathDir) ){
$relPathDir=getcwd();
//echo "relPathDir=$relPathDir\n";
} elseif ($relPathDir{0} != '/'){
trigger_error('phpc_absPath: $relPathDir must begin with "/"', E_USER_ERROR);
}
$path = phpc_str2path( $relPathDir.'/'.$path );
} else {
$path = phpc_str2path( $path );
}
return $path;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/// phpc_require_once
/**
* @desc works around Bug #22775: Fatal error from require() exits with status=0
* @param string $file
* @return void
*/
function phpc_require_once( $file ){
$success=include_once($file);
if (!$success){
trigger_error("phpc_require_once(): failed including file:\n $file\n", E_USER_ERROR);
}
}
//////////////////////////////////////////////////////////////////////
/// phpc_setenv
/**
* @desc set some PHP environmental variables to mimic php -f environment
*
* @param string $phpc_source_file
* @return void
*/
function phpc_setenv( $phpc_source_file ){
global $HTTP_SERVER_VARS;
$keys = array(
"PHP_SELF",
"SCRIPT_NAME",
"SCRIPT_FILENAME",
"PATH_TRANSLATED"
);
foreach ($keys as $i => $key){
$_SERVER[$key]=$HTTP_SERVER_VARS[$key] = $phpc_source_file;
}
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/// phpc_str2path
/**
* @desc return a path; similar to realpath except it doesn't return false if file doesn't exist
*
* @param
* @return string
Derived from make_path written by "Jon Kraft" <sherq@yahoo.de>
- Justin Koivisto <justink@wafishermn.com>
Modified by Greg Keranen <gk@proliberty.com>
*/
function phpc_str2path($path_str){
$pwd=realpath($path_str);
if(empty($pwd)){
$pwd='';
$strArr=preg_split("/(\/)/",$path_str,-1,PREG_SPLIT_NO_EMPTY);
$pwdArr="";
$j=0;
for($i=0;$i<count($strArr);$i++){
if($strArr[$i]!=".."){
if($strArr[$i]!="."){
$pwdArr[$j]=$strArr[$i];
$j++;
}
}else{
array_pop($pwdArr);
$j--;
}
}
$pStr=implode("/",$pwdArr);
$pwd=(strlen($pStr)>0) ? ("/".$pStr) : "/";
}
return $pwd;
} // phpc_str2path
?>
>> << Copyright (c) 2003, Gregory Keranen. All rights reserved. |