register( "darkphp" ,self::$darkphpFolder ); self::$instance = $this; $this->handleCb = array( &$this ,'autoload' ); if ( ! @\ini_get('allow_url_include') ) throw new \Exception( "in conf ini 'allow_url_include' is false.".\PHP_EOL ); elseif ( ! \ini_get('allow_url_fopen') ) throw new \Exception( "in conf ini 'allow_url_fopen' is false.".\PHP_EOL ); elseif ( ! \function_exists( 'spl_autoload_register' ) ) throw new \Exception( "no function 'spl_autoload_register'.".\PHP_EOL ); else { //echo "[bakuba kernel autoload DwAutoLoadBoot] try autoload : bakuba kernel autoload DwAutoLoad".\PHP_EOL; //$this->autoload( "bakuba\\kernel\\autoload\\DwAutoLoad" ); $this->enableAutoload(); } if ( ! isset( $this->log ) || \is_null( $this->log ) ) { if ( defined("logByEcho") ) { $anLog = \darkphp\logger\DwEchoLogger::getFirstLogger( $this ,$logSection ,$logUnit ); } else { $anLog = \darkphp\logger\DwBuffLogger::getFirstLogger( $this ,$logSection ,$logUnit ); } $anLog->info( "try lunch autoload."); $this->setDebug( $anLog ); } else $anLog = $this->log; DwAutoLoad::singleton( $this )->setDebug( $anLog ); if ( defined("logByEcho") ) $this->log->info( "started" ); } public function getLogger( $forThisObject ) : \darkphp\logger\iDwLogger { $pathLogger="unknow\\unknow"; if ( \is_null( $forThisObject ) ) $pathLogger="unknow\\null"; elseif ( \is_object( $forThisObject ) ) { if ( $forThisObject == $this ) $pathLogger = "autoload\\DwAutoLoadBoot"; else $pathLogger = \get_class( $forThisObject ); } else $pathLogger="unknow\\".\gettype( $forThisObject ); /* if ( \method_exists( $this->log ,"upTo" ) ) $iDwLogger = $this->log->upTo( $this ,DwSource::classNameToSectionName( $pathLogger ) ,DwSource::classNameToTopName( $pathLogger ) ); else //*/ if ( \method_exists( $this->log ,"upTo" ) ) $iDwLogger = $this->log->upTo( $forThisObject ,DwSource::classNameToSectionName( $pathLogger ) ,DwSource::classNameToTopName( $pathLogger ) ); else $iDwLogger = $this->log->getLogger( $forThisObject ); return $iDwLogger; } public function setDebug( \darkphp\logger\iDwLogger $iDwLogger ) : void { $this->log = $iDwLogger; $realLogger = $this->getLogger( $this ); $this->log = $realLogger; //$this->log = $iDwLogger->getLogger( $this ); } private $isActiveAutoLoad = false; public function enableAutoload() : bool { if ( $this->isActiveAutoLoad ) throw new \Error( "autoload active yet.".\PHP_EOL ); else $this->isActiveAutoLoad = \spl_autoload_register( $this->handleCb ); ///* if ( $this->isActiveAutoLoad ) { \set_error_handler( array( &$this ,'error_handle' ) ); \set_exception_handler( array( &$this ,'exception_handler' ) ); } //*/ return $this->isActiveAutoLoad; } public function disableAutoload() : bool { $success = false; if ( ! $this->isActiveAutoLoad ) throw new \Exception( "autoload not active yet." ); if ( true === ( $success =\spl_autoload_unregister( $this->handleCb ) ) ) $this->isActiveAutoLoad=false; if ( ! $this->isActiveAutoLoad ) { \restore_error_handler(); \restore_exception_handler(); } /* foreach( \spl_autoload_functions() as $function) if ( $this->handleCb == $function ) $this->isActiveAutoLoad=\spl_autoload_unregister( $function ); //*/ return $success; } private static $ignoreError = array( // "msg_send(): msgsnd failed: Resource temporarily unavailable" ); public function error_handle(int $errno, string $errstr, string $errfile = "file?", int $errline = -1, array $errcontext = null) : bool { //if ( array_search( $errstr, self::$ignoreError ) === false ) { $fileContent = self::decodeFile( $errfile ); if ( \is_string( $fileContent ) ) $errObjStr = " object '".( DwSource::codeToNs( $fileContent ). "\\" . DwSource::codeToClass( $fileContent ) )."'"; if ( \darkphp\string\DwString::startWith( $errfile ,"data://" ) ) $errFileStr = "'data...'"; else $errFileStr = $errfile; $dbgMsg="=================== DwAutoLoadBoot->error_handle".\PHP_EOL; $dbgMsg.=" file:{$errFileStr} l:{$errline} [NoErr:{$errno}]".\PHP_EOL; $dbgMsg.=$errObjStr.\PHP_EOL.\PHP_EOL; $dbgMsg.=" msg:{$errstr}".\PHP_EOL; $dbgMsg.="=================== context".\PHP_EOL; //$dbgMsg.=DwObject::print_r( $errcontext ).\PHP_EOL; $dbgMsg.="=================== END DwAutoLoadBoot->error_handle".\PHP_EOL; if ( isset( $this->log ) && \is_object( $this->log ) ) $this->log->fatal( $dbgMsg ); elseif ( defined("logByEcho") ) echo \PHP_EOL.$dbgMsg.\PHP_EOL; else self::debugWrite( $dbgMsg ); //} return false; } public function exception_handler( $exception ) : void { if ( isset( $this->log ) && \is_object( $this->log ) ) $this->log->fatal( $exception ); elseif ( defined("logByEcho") ) echo \PHP_EOL.self::exceptionToString( $exception ).\PHP_EOL; else self::debugWrite( self::exceptionToString( $exception ) ); } public static function exceptionToString( $exception ) : string { //\darkphp\error\DwException $throwToStr = "=================== DwAutoLoadBoot::exceptionToString".\PHP_EOL; if ( \is_object( $exception ) && \method_exists( $exception, "getMessage" ) ) { $throwToStr.= $exception->getMessage().\PHP_EOL.$exception->getCode().\PHP_EOL; $file = $exception->getFile(); if ( self::_isFile( $file ) ) { $fileContent = self::_getFile( "file://".$file ); $throwToStr.= \darkphp\source\DwSource::formatContentLine( $fileContent ,$exception->getLine() ).\PHP_EOL.\PHP_EOL; } else $throwToStr.= "no file '{$file}'".\PHP_EOL; //darkphp\source\DwSource::getLine( self::decodeFile( $exception->getFile() ) ,$exception->getLine() ); //$backTraceArray = $exception->getTrace(); $previous = $exception->getPrevious(); if ( \is_object( $previous ) ) $throwToStr.=self::exceptionToString( $previous ); } else $throwToStr.= $exception.\PHP_EOL; return $throwToStr; } public function autoload( string $className ) { try { $dbgMsg = "autoloadBoot:$className"; if ( defined("logByEcho") ) { if ( isset( $this->log ) && \is_object( $this->log ) ) $this->log->info( $dbgMsg ); else echo $dbgMsg.\PHP_EOL; } $fileContent = $this->getFile( "file://".\darkphp\source\DwSource::classNameToFileName( $className ) ); $dbgMsg = "no source for '$className' fileContent:'$fileContent'."; if ( \is_string( $fileContent ) ) require_once( "data://text/plain,".\urlencode( $fileContent ) ); elseif ( isset( $this->log ) && \is_object( $this->log ) ) $this->log->info( $dbgMsg ); elseif ( defined("logByEcho") ) echo $dbgMsg.\PHP_EOL; //} catch(\Exception | \Error $throwable) { } catch( \Exception $exception ) { $this->throwError( $exception ,$className ); throw $exception; } catch( \Error $error ) { $this->throwError( $error ,$className ); throw $error; } } protected function throwError( $throwable ,string $className ) { if ( isset( $this->log ) && \is_object( $this->log ) ) $this->log->error( $error ); elseif ( defined("logByEcho") ) echo \PHP_EOL.$this->throwToMsg( $throwable ,$className ).\PHP_EOL; else self::debugWrite( $this->throwToMsg( $throwable ,$className ) ); } protected function liteThrowToMsg( $throwable ,string $className ) : string { return "[".__CLASS__.":".__METHOD__."(pid:".\getmypid().")]\r\n\t Exception autoloadBoot[{$className}]" ."\r\n\t Line:".$throwable->getLine() ."\r\n\t File:".$throwable->getFile() ."\r\n\t Message:\r\n\t\t".$throwable->getMessage()// ."\r\n\t Code:".$throwable->getCode() // ."\r\n\t Trace:".$throwable->getTrace()."\r\n\t" // ."\r\n\t Trace:".$throwable->getTraceAsString()."\r\n\t" // ."\r\n\t Previous:".$throwable->getPrevious()."\r\n\t" ."\r\n"; } public function toString( $withParent = false ) : string { return $this->getClassName(); } public function __destruct() { if ( isset( $this->log ) && \is_object( $this->log ) ) $this->log->info( "ended" ); elseif ( defined("logByEcho") ) echo \PHP_EOL." == DwAutoLoadBoot destruct.".\PHP_EOL; //$this->log->trace( "." ); //parent::__destruct(); foreach( $this as $key => $toDestruct ) if ( isset( $this->$key ) ) unset( $this->$key ); } public function getClassName( bool $fqcn=null ) : string { return self::getStaticClassName( $fqcn ); } public static function getStaticClassName( bool $fqcn=null ) : string { return $fqcn ? "//".self::CLASS_SEPARATOR.__CLASS__ : __CLASS__; } public const CLASS_SEPARATOR = "-"; // \darkphp\autoload\DwAutoLoadBoot::decodeFile( $file ); public static function decodeFile( $file ) : string { $decoded=""; if ( \is_string( $file ) ) { $fileLen = \strlen( $file ); $b64 = "data://text/plain;base64,"; $b64Len = \strlen( $b64 ); $uenc = "data://text/plain,"; $uencLen = \strlen( $uenc ); if ( $fileLen > $b64Len && $b64 == \substr( $file,0 ,$b64Len ) ) $decoded = \base64_decode( \substr( $file ,$b64Len ) ); elseif ( $fileLen > $uencLen && $uenc == \substr( $file,0 ,$uencLen ) ) $decoded = \urldecode( \substr( $file ,$uencLen ) ); else $decoded=\substr($file,0,100)."....\r\n"; } elseif ( \is_array( $file ) ) { if ( isset( $file["file"] ) ) $decoded= self::decodeFile( $file["file"] ); } return $decoded; } private static function _getFile( string $filePath ) : ?string { return self::$instance->getFile( $filePath ); } private static function _isFile( string $filePath ) : bool { return self::$instance->isFile( $filePath ); } private static function throwToMsg( $throwable ,string $className ,$first = true ) : string { $traceData = DwSource::formatFileLine( $throwable->getFile() ,$throwable->getLine() ); $dbgMsg = ( $first ? "[pid:".\getmypid()."] Exception autoloadFile" : "-----------------------" ).\PHP_EOL; $dbgMsg .= "\t[{$className}] /code(" . $throwable->getCode().")".\PHP_EOL; $dbgMsg .= " [ ".$throwable->getMessage()." ]".\PHP_EOL; $dbgMsg .= "\t".( empty ( $traceData ) ? "" : $traceData ).\PHP_EOL; foreach( $throwable->getTrace() as $trace ) { //if ( $trace['function'] == 'theAutoload' || $trace['function']=='autoload' ) // continue; $dbgMsg.="\t\t".self::traceError( $trace ).\PHP_EOL; } $previous = $throwable->getPrevious(); if ( \is_object( $previous ) ) $dbgMsg.=self::throwToMsg( $previous ,$className ,false ); $dbgMsg.="=======================================================================".\PHP_EOL; return $dbgMsg; } //darkphp\error\DwTrace::traceError( $trace ); private static function traceError( $trace ) : string { //[ 'file' ,'line' ,'class' ,'type' ,'function' ,'object','args' ] if ( isset ( $trace['line'] ) ) { $line = $trace['line']; if ( isset( $trace['file'] ) && \is_int( $line ) ) $file = DwSource::formatFileLine( $trace['file'] ,$line ); else $file = "FileNotSet(l:{$line})!"; }elseif ( isset( $trace['file'] ) ) $file = "File(".$trace['file'].")!"; $args=""; if ( isset( $trace['args'] ) && \is_array( $trace['args'] ) ) foreach( $trace['args'] as $arg ) { if ( ! empty( $args ) ) $args=" ,"; if ( \is_object( $arg ) ) $args.=\get_class( $arg ); elseif ( \is_array( $arg ) ) $args="'array'"; else $args="'{$arg}'"; } $strHead=""; if ( isset( $trace['class'] ) ) $strHead.=$trace['class']; if ( isset( $trace['type'] ) ) $strHead.=$trace['type']; else $strHead.="_>"; if ( isset( $trace['function'] ) ) $strHead.=$trace['function']; return "/" . $strHead ."(" . ( empty( $args ) ? "" : " {$args} " ). ") " . ( empty( $file ) ? "" : $file ); } private static function getErrStream() { static $err = null; if ($err !== null) { return $err; } if (\PHP_SAPI === 'cli' || \PHP_SAPI === 'phpdbg') { if ( \defined('STDERR') && \is_resource(\STDERR) ) { return $err = \STDERR; } } $h = @\fopen('php://stderr', 'wb'); if (\is_resource($h)) { return $err = $h; } return $err = false; } public static function debugWrite($dbgMsg) { echo \rtrim($dbgMsg, "\r\n"); $err = self::getErrStream(); if (\is_resource($err)) { @\fwrite($err, $dbgMsg); return; } \error_log(\rtrim($dbgMsg, "\r\n")); } } ?>