3
* This file is part of PHPUnit.
5
* (c) Sebastian Bergmann <sebastian@phpunit.de>
7
* For the full copyright and license information, please view the LICENSE
8
* file that was distributed with this source code.
12
* Wrapper for the PHPUnit XML configuration file.
14
* Example XML configuration file:
16
* <?xml version="1.0" encoding="utf-8" ?>
18
* <phpunit backupGlobals="true"
19
* backupStaticAttributes="false"
20
* bootstrap="/path/to/bootstrap.php"
24
* convertErrorsToExceptions="true"
25
* convertNoticesToExceptions="true"
26
* convertWarningsToExceptions="true"
27
* forceCoversAnnotation="false"
28
* mapTestClassNameToCoveredClassName="false"
29
* printerClass="PHPUnit_TextUI_ResultPrinter"
30
* processIsolation="false"
32
* stopOnFailure="false"
33
* stopOnIncomplete="false"
35
* stopOnSkipped="false"
36
* testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
37
* timeoutForSmallTests="1"
38
* timeoutForMediumTests="10"
39
* timeoutForLargeTests="60"
40
* beStrictAboutTestsThatDoNotTestAnything="false"
41
* beStrictAboutOutputDuringTests="false"
42
* beStrictAboutTestSize="false"
43
* beStrictAboutTodoAnnotatedTests="false"
44
* checkForUnintentionallyCoveredCode="false"
47
* <testsuite name="My Test Suite">
48
* <directory suffix="Test.php" phpVersion="5.3.0" phpVersionOperator=">=">/path/to/files</directory>
49
* <file phpVersion="5.3.0" phpVersionOperator=">=">/path/to/MyTest.php</file>
50
* <exclude>/path/to/files/exclude</exclude>
65
* <directory suffix=".php">/path/to/files</directory>
66
* <file>/path/to/file</file>
68
* <directory suffix=".php">/path/to/files</directory>
69
* <file>/path/to/file</file>
72
* <whitelist addUncoveredFilesFromWhitelist="true"
73
* processUncoveredFilesFromWhitelist="false">
74
* <directory suffix=".php">/path/to/files</directory>
75
* <file>/path/to/file</file>
77
* <directory suffix=".php">/path/to/files</directory>
78
* <file>/path/to/file</file>
84
* <listener class="MyListener" file="/optional/path/to/MyListener.php">
88
* <string>Sebastian</string>
91
* <integer>22</integer>
92
* <string>April</string>
93
* <double>19.78</double>
95
* <object class="stdClass"/>
96
* <file>MyRelativeFile.php</file>
97
* <directory>MyRelativeDir</directory>
103
* <log type="coverage-html" target="/tmp/report" lowUpperBound="50" highLowerBound="90"/>
104
* <log type="coverage-clover" target="/tmp/clover.xml"/>
105
* <log type="json" target="/tmp/logfile.json"/>
106
* <log type="plain" target="/tmp/logfile.txt"/>
107
* <log type="tap" target="/tmp/logfile.tap"/>
108
* <log type="junit" target="/tmp/logfile.xml" logIncompleteSkipped="false"/>
109
* <log type="testdox-html" target="/tmp/testdox.html"/>
110
* <log type="testdox-text" target="/tmp/testdox.txt"/>
111
* <log type="coverage-crap4j" target="/tmp/crap.xml"/>
115
* <includePath>.</includePath>
116
* <ini name="foo" value="bar"/>
117
* <const name="foo" value="bar"/>
118
* <var name="foo" value="bar"/>
119
* <env name="foo" value="bar"/>
120
* <post name="foo" value="bar"/>
121
* <get name="foo" value="bar"/>
122
* <cookie name="foo" value="bar"/>
123
* <server name="foo" value="bar"/>
124
* <files name="foo" value="bar"/>
125
* <request name="foo" value="bar"/>
129
* <browser name="Firefox on Linux"
130
* browser="*firefox /usr/lib/firefox/firefox-bin"
131
* host="my.linux.box"
140
* @author Sebastian Bergmann <sebastian@phpunit.de>
141
* @copyright Sebastian Bergmann <sebastian@phpunit.de>
142
* @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
143
* @link http://www.phpunit.de/
144
* @since Class available since Release 3.2.0
146
class PHPUnit_Util_Configuration
148
private static $instances = array();
155
* Loads a PHPUnit configuration file.
157
* @param string $filename
159
protected function __construct($filename)
161
$this->filename = $filename;
162
$this->document = PHPUnit_Util_XML::loadFile($filename, false, true, true);
163
$this->xpath = new DOMXPath($this->document);
167
* @since Method available since Release 3.4.0
169
final private function __clone()
174
* Returns a PHPUnit configuration object.
176
* @param string $filename
177
* @return PHPUnit_Util_Configuration
178
* @since Method available since Release 3.4.0
180
public static function getInstance($filename)
182
$realpath = realpath($filename);
184
if ($realpath === false) {
185
throw new PHPUnit_Framework_Exception(
187
'Could not read "%s".',
193
if (!isset(self::$instances[$realpath])) {
194
self::$instances[$realpath] = new PHPUnit_Util_Configuration($realpath);
197
return self::$instances[$realpath];
201
* Returns the realpath to the configuration file.
204
* @since Method available since Release 3.6.0
206
public function getFilename()
208
return $this->filename;
212
* Returns the configuration for SUT filtering.
215
* @since Method available since Release 3.2.1
217
public function getFilterConfiguration()
219
$addUncoveredFilesFromWhitelist = true;
220
$processUncoveredFilesFromWhitelist = false;
222
$tmp = $this->xpath->query('filter/whitelist');
224
if ($tmp->length == 1) {
225
if ($tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) {
226
$addUncoveredFilesFromWhitelist = $this->getBoolean(
227
(string) $tmp->item(0)->getAttribute(
228
'addUncoveredFilesFromWhitelist'
234
if ($tmp->item(0)->hasAttribute('processUncoveredFilesFromWhitelist')) {
235
$processUncoveredFilesFromWhitelist = $this->getBoolean(
236
(string) $tmp->item(0)->getAttribute(
237
'processUncoveredFilesFromWhitelist'
245
'blacklist' => array(
247
'directory' => $this->readFilterDirectories(
248
'filter/blacklist/directory'
250
'file' => $this->readFilterFiles(
251
'filter/blacklist/file'
255
'directory' => $this->readFilterDirectories(
256
'filter/blacklist/exclude/directory'
258
'file' => $this->readFilterFiles(
259
'filter/blacklist/exclude/file'
263
'whitelist' => array(
264
'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist,
265
'processUncoveredFilesFromWhitelist' => $processUncoveredFilesFromWhitelist,
267
'directory' => $this->readFilterDirectories(
268
'filter/whitelist/directory'
270
'file' => $this->readFilterFiles(
271
'filter/whitelist/file'
275
'directory' => $this->readFilterDirectories(
276
'filter/whitelist/exclude/directory'
278
'file' => $this->readFilterFiles(
279
'filter/whitelist/exclude/file'
287
* Returns the configuration for groups.
290
* @since Method available since Release 3.2.1
292
public function getGroupConfiguration()
295
'include' => array(),
299
foreach ($this->xpath->query('groups/include/group') as $group) {
300
$groups['include'][] = (string) $group->nodeValue;
303
foreach ($this->xpath->query('groups/exclude/group') as $group) {
304
$groups['exclude'][] = (string) $group->nodeValue;
311
* Returns the configuration for listeners.
314
* @since Method available since Release 3.4.0
316
public function getListenerConfiguration()
320
foreach ($this->xpath->query('listeners/listener') as $listener) {
321
$class = (string) $listener->getAttribute('class');
323
$arguments = array();
325
if ($listener->getAttribute('file')) {
326
$file = $this->toAbsolutePath(
327
(string) $listener->getAttribute('file'), true
331
foreach ($listener->childNodes as $node) {
332
if ($node instanceof DOMElement && $node->tagName == 'arguments') {
333
foreach ($node->childNodes as $argument) {
334
if ($argument instanceof DOMElement) {
335
if ($argument->tagName == 'file' ||
336
$argument->tagName == 'directory') {
337
$arguments[] = $this->toAbsolutePath((string) $argument->nodeValue);
339
$arguments[] = PHPUnit_Util_XML::xmlToVariable($argument);
349
'arguments' => $arguments
357
* Returns the logging configuration.
361
public function getLoggingConfiguration()
365
foreach ($this->xpath->query('logging/log') as $log) {
366
$type = (string) $log->getAttribute('type');
367
$target = (string) $log->getAttribute('target');
373
$target = $this->toAbsolutePath($target);
375
if ($type == 'coverage-html') {
376
if ($log->hasAttribute('lowUpperBound')) {
377
$result['lowUpperBound'] = (string) $log->getAttribute('lowUpperBound');
380
if ($log->hasAttribute('highLowerBound')) {
381
$result['highLowerBound'] = (string) $log->getAttribute('highLowerBound');
383
} elseif ($type == 'junit') {
384
if ($log->hasAttribute('logIncompleteSkipped')) {
385
$result['logIncompleteSkipped'] = $this->getBoolean(
386
(string) $log->getAttribute('logIncompleteSkipped'),
390
} elseif ($type == 'coverage-text') {
391
if ($log->hasAttribute('showUncoveredFiles')) {
392
$result['coverageTextShowUncoveredFiles'] = $this->getBoolean(
393
(string) $log->getAttribute('showUncoveredFiles'),
397
if ($log->hasAttribute('showOnlySummary')) {
398
$result['coverageTextShowOnlySummary'] = $this->getBoolean(
399
(string) $log->getAttribute('showOnlySummary'),
405
$result[$type] = $target;
412
* Returns the PHP configuration.
415
* @since Method available since Release 3.2.1
417
public function getPHPConfiguration()
420
'include_path' => array(),
433
foreach ($this->xpath->query('php/includePath') as $includePath) {
434
$path = (string) $includePath->nodeValue;
436
$result['include_path'][] = $this->toAbsolutePath($path);
440
foreach ($this->xpath->query('php/ini') as $ini) {
441
$name = (string) $ini->getAttribute('name');
442
$value = (string) $ini->getAttribute('value');
444
$result['ini'][$name] = $value;
447
foreach ($this->xpath->query('php/const') as $const) {
448
$name = (string) $const->getAttribute('name');
449
$value = (string) $const->getAttribute('value');
451
$result['const'][$name] = $this->getBoolean($value, $value);
454
foreach (array('var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
455
foreach ($this->xpath->query('php/' . $array) as $var) {
456
$name = (string) $var->getAttribute('name');
457
$value = (string) $var->getAttribute('value');
459
$result[$array][$name] = $this->getBoolean($value, $value);
467
* Handles the PHP configuration.
469
* @since Method available since Release 3.2.20
471
public function handlePHPConfiguration()
473
$configuration = $this->getPHPConfiguration();
475
if (! empty($configuration['include_path'])) {
478
implode(PATH_SEPARATOR, $configuration['include_path']) .
480
ini_get('include_path')
484
foreach ($configuration['ini'] as $name => $value) {
485
if (defined($value)) {
486
$value = constant($value);
489
ini_set($name, $value);
492
foreach ($configuration['const'] as $name => $value) {
493
if (!defined($name)) {
494
define($name, $value);
498
foreach (array('var', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
499
// See https://github.com/sebastianbergmann/phpunit/issues/277
510
$target = &$GLOBALS['_' . strtoupper($array)];
514
foreach ($configuration[$array] as $name => $value) {
515
$target[$name] = $value;
519
foreach ($configuration['env'] as $name => $value) {
520
if (false === getenv($name)) {
521
putenv("{$name}={$value}");
523
if (!isset($_ENV[$name])) {
524
$_ENV[$name] = $value;
530
* Returns the PHPUnit configuration.
533
* @since Method available since Release 3.2.14
535
public function getPHPUnitConfiguration()
538
$root = $this->document->documentElement;
540
if ($root->hasAttribute('cacheTokens')) {
541
$result['cacheTokens'] = $this->getBoolean(
542
(string) $root->getAttribute('cacheTokens'), false
546
if ($root->hasAttribute('colors')) {
547
$result['colors'] = $this->getBoolean(
548
(string) $root->getAttribute('colors'), false
555
if ($root->hasAttribute('stderr')) {
556
$result['stderr'] = $this->getBoolean(
557
(string)$root->getAttribute('stderr'), false
561
if ($root->hasAttribute('backupGlobals')) {
562
$result['backupGlobals'] = $this->getBoolean(
563
(string) $root->getAttribute('backupGlobals'), true
567
if ($root->hasAttribute('backupStaticAttributes')) {
568
$result['backupStaticAttributes'] = $this->getBoolean(
569
(string) $root->getAttribute('backupStaticAttributes'), false
573
if ($root->getAttribute('bootstrap')) {
574
$result['bootstrap'] = $this->toAbsolutePath(
575
(string) $root->getAttribute('bootstrap')
579
if ($root->hasAttribute('convertErrorsToExceptions')) {
580
$result['convertErrorsToExceptions'] = $this->getBoolean(
581
(string) $root->getAttribute('convertErrorsToExceptions'), true
585
if ($root->hasAttribute('convertNoticesToExceptions')) {
586
$result['convertNoticesToExceptions'] = $this->getBoolean(
587
(string) $root->getAttribute('convertNoticesToExceptions'), true
591
if ($root->hasAttribute('convertWarningsToExceptions')) {
592
$result['convertWarningsToExceptions'] = $this->getBoolean(
593
(string) $root->getAttribute('convertWarningsToExceptions'), true
597
if ($root->hasAttribute('forceCoversAnnotation')) {
598
$result['forceCoversAnnotation'] = $this->getBoolean(
599
(string) $root->getAttribute('forceCoversAnnotation'), false
603
if ($root->hasAttribute('mapTestClassNameToCoveredClassName')) {
604
$result['mapTestClassNameToCoveredClassName'] = $this->getBoolean(
605
(string) $root->getAttribute('mapTestClassNameToCoveredClassName'),
610
if ($root->hasAttribute('processIsolation')) {
611
$result['processIsolation'] = $this->getBoolean(
612
(string) $root->getAttribute('processIsolation'), false
616
if ($root->hasAttribute('stopOnError')) {
617
$result['stopOnError'] = $this->getBoolean(
618
(string) $root->getAttribute('stopOnError'), false
622
if ($root->hasAttribute('stopOnFailure')) {
623
$result['stopOnFailure'] = $this->getBoolean(
624
(string) $root->getAttribute('stopOnFailure'), false
628
if ($root->hasAttribute('stopOnIncomplete')) {
629
$result['stopOnIncomplete'] = $this->getBoolean(
630
(string) $root->getAttribute('stopOnIncomplete'), false
634
if ($root->hasAttribute('stopOnRisky')) {
635
$result['stopOnRisky'] = $this->getBoolean(
636
(string) $root->getAttribute('stopOnRisky'), false
640
if ($root->hasAttribute('stopOnSkipped')) {
641
$result['stopOnSkipped'] = $this->getBoolean(
642
(string) $root->getAttribute('stopOnSkipped'), false
646
if ($root->hasAttribute('testSuiteLoaderClass')) {
647
$result['testSuiteLoaderClass'] = (string) $root->getAttribute(
648
'testSuiteLoaderClass'
652
if ($root->getAttribute('testSuiteLoaderFile')) {
653
$result['testSuiteLoaderFile'] = $this->toAbsolutePath(
654
(string) $root->getAttribute('testSuiteLoaderFile')
658
if ($root->hasAttribute('printerClass')) {
659
$result['printerClass'] = (string) $root->getAttribute(
664
if ($root->getAttribute('printerFile')) {
665
$result['printerFile'] = $this->toAbsolutePath(
666
(string) $root->getAttribute('printerFile')
670
if ($root->hasAttribute('timeoutForSmallTests')) {
671
$result['timeoutForSmallTests'] = $this->getInteger(
672
(string) $root->getAttribute('timeoutForSmallTests'), 1
676
if ($root->hasAttribute('timeoutForMediumTests')) {
677
$result['timeoutForMediumTests'] = $this->getInteger(
678
(string) $root->getAttribute('timeoutForMediumTests'), 10
682
if ($root->hasAttribute('timeoutForLargeTests')) {
683
$result['timeoutForLargeTests'] = $this->getInteger(
684
(string) $root->getAttribute('timeoutForLargeTests'), 60
688
if ($root->hasAttribute('beStrictAboutTestsThatDoNotTestAnything')) {
689
$result['reportUselessTests'] = $this->getBoolean(
690
(string) $root->getAttribute('beStrictAboutTestsThatDoNotTestAnything'), false
694
if ($root->hasAttribute('checkForUnintentionallyCoveredCode')) {
695
$result['strictCoverage'] = $this->getBoolean(
696
(string) $root->getAttribute('checkForUnintentionallyCoveredCode'), false
700
if ($root->hasAttribute('beStrictAboutOutputDuringTests')) {
701
$result['disallowTestOutput'] = $this->getBoolean(
702
(string) $root->getAttribute('beStrictAboutOutputDuringTests'), false
706
if ($root->hasAttribute('beStrictAboutTestSize')) {
707
$result['enforceTimeLimit'] = $this->getBoolean(
708
(string) $root->getAttribute('beStrictAboutTestSize'), false
712
if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) {
713
$result['disallowTodoAnnotatedTests'] = $this->getBoolean(
714
(string) $root->getAttribute('beStrictAboutTodoAnnotatedTests'), false
718
if ($root->hasAttribute('strict')) {
719
$flag = $this->getBoolean(
720
(string) $root->getAttribute('strict'), false
723
$result['reportUselessTests'] = $flag;
724
$result['strictCoverage'] = $flag;
725
$result['disallowTestOutput'] = $flag;
726
$result['enforceTimeLimit'] = $flag;
727
$result['disallowTodoAnnotatedTests'] = $flag;
730
if ($root->hasAttribute('verbose')) {
731
$result['verbose'] = $this->getBoolean(
732
(string) $root->getAttribute('verbose'), false
740
* Returns the SeleniumTestCase browser configuration.
743
* @since Method available since Release 3.2.9
745
public function getSeleniumBrowserConfiguration()
749
foreach ($this->xpath->query('selenium/browser') as $config) {
750
$name = (string) $config->getAttribute('name');
751
$browser = (string) $config->getAttribute('browser');
753
if ($config->hasAttribute('host')) {
754
$host = (string) $config->getAttribute('host');
759
if ($config->hasAttribute('port')) {
760
$port = $this->getInteger(
761
(string) $config->getAttribute('port'), 4444
767
if ($config->hasAttribute('timeout')) {
768
$timeout = $this->getInteger(
769
(string) $config->getAttribute('timeout'), 30000
777
'browser' => $browser,
780
'timeout' => $timeout
788
* Returns the test suite configuration.
790
* @return PHPUnit_Framework_TestSuite
791
* @since Method available since Release 3.2.1
793
public function getTestSuiteConfiguration($testSuiteFilter = null)
795
$testSuiteNodes = $this->xpath->query('testsuites/testsuite');
797
if ($testSuiteNodes->length == 0) {
798
$testSuiteNodes = $this->xpath->query('testsuite');
801
if ($testSuiteNodes->length == 1) {
802
return $this->getTestSuite($testSuiteNodes->item(0), $testSuiteFilter);
805
if ($testSuiteNodes->length > 1) {
806
$suite = new PHPUnit_Framework_TestSuite;
808
foreach ($testSuiteNodes as $testSuiteNode) {
809
$suite->addTestSuite(
810
$this->getTestSuite($testSuiteNode, $testSuiteFilter)
819
* @param DOMElement $testSuiteNode
820
* @return PHPUnit_Framework_TestSuite
821
* @since Method available since Release 3.4.0
823
protected function getTestSuite(DOMElement $testSuiteNode, $testSuiteFilter = null)
825
if ($testSuiteNode->hasAttribute('name')) {
826
$suite = new PHPUnit_Framework_TestSuite(
827
(string) $testSuiteNode->getAttribute('name')
830
$suite = new PHPUnit_Framework_TestSuite;
835
foreach ($testSuiteNode->getElementsByTagName('exclude') as $excludeNode) {
836
$excludeFile = (string) $excludeNode->nodeValue;
838
$exclude[] = $this->toAbsolutePath($excludeFile);
842
$fileIteratorFacade = new File_Iterator_Facade;
844
foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) {
845
if ($testSuiteFilter && $directoryNode->parentNode->getAttribute('name') != $testSuiteFilter) {
849
$directory = (string) $directoryNode->nodeValue;
851
if (empty($directory)) {
855
if ($directoryNode->hasAttribute('phpVersion')) {
856
$phpVersion = (string) $directoryNode->getAttribute('phpVersion');
858
$phpVersion = PHP_VERSION;
861
if ($directoryNode->hasAttribute('phpVersionOperator')) {
862
$phpVersionOperator = (string) $directoryNode->getAttribute('phpVersionOperator');
864
$phpVersionOperator = '>=';
867
if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
871
if ($directoryNode->hasAttribute('prefix')) {
872
$prefix = (string) $directoryNode->getAttribute('prefix');
877
if ($directoryNode->hasAttribute('suffix')) {
878
$suffix = (string) $directoryNode->getAttribute('suffix');
880
$suffix = 'Test.php';
883
$files = $fileIteratorFacade->getFilesAsArray(
884
$this->toAbsolutePath($directory),
889
$suite->addTestFiles($files);
892
foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) {
893
if ($testSuiteFilter && $fileNode->parentNode->getAttribute('name') != $testSuiteFilter) {
897
$file = (string) $fileNode->nodeValue;
903
// Get the absolute path to the file
904
$file = $fileIteratorFacade->getFilesAsArray(
905
$this->toAbsolutePath($file)
908
if (!isset($file[0])) {
914
if ($fileNode->hasAttribute('phpVersion')) {
915
$phpVersion = (string) $fileNode->getAttribute('phpVersion');
917
$phpVersion = PHP_VERSION;
920
if ($fileNode->hasAttribute('phpVersionOperator')) {
921
$phpVersionOperator = (string) $fileNode->getAttribute('phpVersionOperator');
923
$phpVersionOperator = '>=';
926
if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
930
$suite->addTestFile($file);
937
* @param string $value
938
* @param boolean $default
940
* @since Method available since Release 3.2.3
942
protected function getBoolean($value, $default)
944
if (strtolower($value) == 'false') {
946
} elseif (strtolower($value) == 'true') {
954
* @param string $value
955
* @param boolean $default
957
* @since Method available since Release 3.6.0
959
protected function getInteger($value, $default)
961
if (is_numeric($value)) {
969
* @param string $query
971
* @since Method available since Release 3.2.3
973
protected function readFilterDirectories($query)
975
$directories = array();
977
foreach ($this->xpath->query($query) as $directory) {
978
$directoryPath = (string) $directory->nodeValue;
980
if (!$directoryPath) {
984
if ($directory->hasAttribute('prefix')) {
985
$prefix = (string) $directory->getAttribute('prefix');
990
if ($directory->hasAttribute('suffix')) {
991
$suffix = (string) $directory->getAttribute('suffix');
996
if ($directory->hasAttribute('group')) {
997
$group = (string) $directory->getAttribute('group');
1002
$directories[] = array(
1003
'path' => $this->toAbsolutePath($directoryPath),
1004
'prefix' => $prefix,
1005
'suffix' => $suffix,
1010
return $directories;
1014
* @param string $query
1016
* @since Method available since Release 3.2.3
1018
protected function readFilterFiles($query)
1022
foreach ($this->xpath->query($query) as $file) {
1023
$filePath = (string) $file->nodeValue;
1025
$files[] = $this->toAbsolutePath($filePath);
1033
* @param string $path
1034
* @param boolean $useIncludePath
1036
* @since Method available since Release 3.5.0
1038
protected function toAbsolutePath($path, $useIncludePath = false)
1040
if ($path[0] === '/') {
1044
// Matches the following on Windows:
1045
// - \\NetworkComputer\Path
1052
if (defined('PHP_WINDOWS_VERSION_BUILD') &&
1053
($path[0] === '\\' ||
1054
(strlen($path) >= 3 && preg_match('#^[A-Z]\:[/\\\]#i', substr($path, 0, 3))))) {
1059
if (strpos($path, '://') !== false) {
1063
$file = dirname($this->filename) . DIRECTORY_SEPARATOR . $path;
1065
if ($useIncludePath && !file_exists($file)) {
1066
$includePathFile = stream_resolve_include_path($path);
1068
if ($includePathFile) {
1069
$file = $includePathFile;