//file index.php

Php get namespace of included file

//file foo.php <?php namespace foo; class foo{ function __construct(){ echo "hello"; } } ?> //file index.php <?php require_once("foo.php"); echo __NAMESPACE__; ?> 

My question is: can I find out from my index.php file that the namespace foo.php does not read the contents of the file and does not make a regular expression on it? It just looks like overhead.

/// EDIT

I would really like to dynamically add a namespace to the included file.

 <?php namespace dynamic; require_once("foo.php"); echo __NAMESPACE__; ?> 

I want to allow third-party plugins, but php namespaces seem terrible. I don’t want the plugin editor to have to create a namespace.

+4
source share
4 answers

No. But you could fool him like this:

 //file foo.php <?php namespace foo; //... return __NAMESPACE__; // must be last line ?> 

And for reading:

 //file index.php <?php $ns = require_once("foo.php"); 
+15
source

Well, you can scan the class namespace. It contains namespaces. This is the way PHPUnit does things. So, ie:

 $namespaces = get_current_namespaces(); include 'plugin/main.php'; $newNamespaces = get_current_namespaces(); array_diff($namespaces, $newNamespaces) 

Here's how you can implement get_current_namespaces() : is it possible to get a list of specific namespaces

+5
source

If you know the file, you can simply extract the namespace form :).

 function extract_namespace($file) { $ns = NULL; $handle = fopen($file, "r"); if ($handle) { while (($line = fgets($handle)) !== false) { if (strpos($line, 'namespace') === 0) { $parts = explode(' ', $line); $ns = rtrim(trim($parts[1]), ';'); break; } } fclose($handle); } return $ns; } 

And you will not hold back the return of anything at the end of the file, which may be hacked from output or other return instructions.

+3
source

I developed a rather laborious manual way to do this.

As discussed above, the process itself is simple:

  • Get a list of files for each file. Now for each file:
  • create a random namespace id
  • crop file and replace first start tag
  • add namespace id and run tag in file
  • write to temp file
  • import temp file
  • any reflection is required and then cleaning

I have an example with some zend here ... maybe not the most efficient, but it works.

 <?php //first setup zend set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__)."/../zend/library/"); require_once 'Zend/Loader/Autoloader.php'; $loader = Zend_Loader_Autoloader::getInstance(); $loader->registerNamespace(dirname(__FILE__)."/../zend/library/"); //include my extender class class Zend_Reflection_File_WithNamespace extends Zend_Reflection_File { public function getFunctionsWithNamespace($namespace = '', $reflectionClass = 'Zend_Reflection_Function') { $functions = array(); foreach ($this->_functions as $function) { $newName = $namespace . "\\" . $function; $instance = new $reflectionClass($newName); if (!$instance instanceof Zend_Reflection_Function) { require_once 'Zend/Reflection/Exception.php'; throw new Zend_Reflection_Exception('Invalid reflection class provided; must extend Zend_Reflection_Function'); } $functions[] = $instance; } return $functions; } } //find file(s) $startDir = 'hello/'; //$tempDir = 'php://temp/resource='; $tempDir = 'temp/'; $fileList = scandir($startDir); function ppPrintR($data) { echo "<pre>"; print_r($data); echo "</pre>"; } //Now loop through each file, first writing to temp, including and then testing foreach ($fileList as $key => &$fileItem) { if (is_file($startDir . $fileItem)) { //Take file and convert it $findDir = $startDir . $fileItem; echo $startDir . $fileItem; $inContents = file_get_contents($findDir); $randIden = 'm' . preg_replace('/\.|\s/', '', microtime()); //Replace the <?[php] at the start of the file with <? namespace xyz; $inContents = trim($inContents); $addString = 'namespace ' . $randIden . '; '; $longTagPos = strpos($inContents,'<?php'); $shortTagPos = strpos($inContents,'<?'); if ($longTagPos !== false && $longTagPos < 10) { $inContents = str_replace('<?php', '', $inContents); $addString = '<?php ' . $addString; } else if ($shortTagPage !== false && $longTagPos < 10) { $inContents = str_replace('<?', '', $inContents); $addString = '<? ' . $addString; } $outContents = $addString . $inContents; //Now write and require new temp file $tempItem = $tempDir . $fileItem; file_put_contents($tempItem, $outContents); require($tempItem); //Now do normal things $reflectedFile = new Zend_Reflection_File_WithNamespace($tempItem); echo 'Before<br/>'; $functions = $reflectedFile->getFunctionsWithNamespace($randIden); echo 'After<br/>'; //Now foreach function, read params and consider execution foreach($functions as &$functionItem) { echo $functionItem->name . "<br/>"; $functionParams = $functionItem->getParameters(); ppPrintR($functionParams); } //FIXME should clean here } } ?> 
0
source

Source: https://habr.com/ru/post/1333081/


All Articles