Source Provider

Data Source Identification

Identify the Data Source with the Symfony Finder Component.

Now, and for the following chapters, we will not mention how you load the classes. Depending of the install strategy you’ve adopted, Composer or other, don’t forget to load your autoloader.

Reflect offers a data source provider mechanism. You may either use the basic Symfony Finder, what we will do next, or use your own.

Basic Provider with Symfony Finder

<?php

use Bartlett\Reflect\Provider\SymfonyFinderProvider;
use Symfony\Component\Finder\Finder;

$dirs = dirname(__DIR__) . '/sources';

$finder = new Finder();
$finder->files()
    ->name('*.php')
    ->in($dirs);

$provider = new SymfonyFinderProvider($finder);

At this step, we have created a data source provider that is allowed to retrieve each element to parse.

Reflect need to know it. We attach then the previous provider instance to a Provider Manager, with a label ( e.g: Single ) to identify it easily.

Reflect Provider Manager with a unique data source
<?php

use Bartlett\Reflect\ProviderManager;

$pm = new ProviderManager;
$pm->set('Single', $provider);
A Provider Manager may provide one or more data source identifications. Equivalent to the source-providers section of the phpreflect.json configuration file for the command-line interface.
Reflect Provider Manager with multiple data sources
<?php

use Bartlett\Reflect\ProviderManager;
use Bartlett\Reflect\Provider\SymfonyFinderProvider;
use Symfony\Component\Finder\Finder;

$pm = new ProviderManager;

// -- source 1
$source1 = dirname(__DIR__) . '/sources/';

$finder1 = new Finder();
$finder1->files()
    ->name('sample1.php')
    ->in($source1);

$pm->set('Sample', new SymfonyFinderProvider($finder1));

// -- source 2
$pharFile = dirname(__DIR__) . '/sources/pirus.phar';
$source2  = 'phar://' . $pharFile;

$finder2 = new Finder();
$finder2->files()
    ->path('/Pirus/')
    ->name('*.php')
    ->in($source2);

$pm->set('Pirus', new SymfonyFinderProvider($finder2));

On this example Reflect is able to parse contents of two data sources: Sample and Pirus, all at once (default behavior) or individually.

Parse elements of the provider

We reuse the provider manager instance ($pm) seen above (unique data source named Single ). Then we ask Reflect to parse its full contents.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;
$reflect->setProviderManager($pm);
$reflect->parse();

In case of multiple data sources, when you want to parse it individually rather than fully, use the following statements.

Parse only Data Source named Pirus
<?php

use Bartlett\Reflect;

$reflect = new Reflect;
$reflect->setProviderManager($pm);
$reflect->parse(array('Pirus'));

Pirus is the data source label used on $pm→set() statement.

You have identified data sources and parsed its full contents. Now you are ready to handle the results.

Handle Results

Study case

We are suppose in the following, study the source code below, script named StudyCase1.php :

<?php
include '/path/to/test1.php';
include_once 'test2.php';
require 'test3.php';
// test four
require_once
    'test4.php';

class Foo implements SplObserver
{
    const FOO = 'default FOO value';

    public function __construct()
    {
    }

    public function update(SplSubject $subject) {
    }
}

define('SOURCE1_ROOT', __DIR__);

function singleFunction( Array $someparam, stdClass $somethingelse, $lastone = NULL )
{
}

To explore and exploit results, we need first to parse the data source. You should be able to do it.

Here are the solution how to parse the data source seen above :

<?php

use Bartlett\Reflect;
use Bartlett\Reflect\ProviderManager;
use Bartlett\Reflect\Provider\SymfonyFinderProvider;
use Symfony\Component\Finder\Finder;

$dirs = dirname(__DIR__) . '/sources';

$finder = new Finder();
$finder->files()
    ->name('StudyCase1.php')
    ->in($dirs);

$provider = new SymfonyFinderProvider($finder);

$pm = new ProviderManager;
$pm->set('StudyCase1', $provider);

$reflect = new Reflect;
$reflect->setProviderManager($pm);
$reflect->parse();

Enumerate each elements

Packages or Namespaces

Your first collection returned could be the list of packages defined in your source code, if any.

Packages or Namespaces are used to organize software elements to avoid conflicts.

Indifferently, we will use the term package or namespace as an alias of the other. Main reason is that PHP5 provides only namespace and not package element as Java.

Reflect returns a list of namespaces/packages with the getPackages() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

$packages = $reflect->getPackages();

This list ($packages) is an iterator, that can be traversed by a simple foreach loop.

Easy exploit namespaces
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    echo $package->getName(), PHP_EOL;
}

Uses

Your last collection returned could be the list of use statements defined in a package, if any.

Reflect returns a list of use statements with the getUses() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $uses = $package->getUses();
}

This list ($uses) is an iterator, that can be traversed by a simple foreach loop.

Easy exploit uses
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getUses() as $use) {
        printf('%s with alias %s%s', $use->getName(), $use->getShortName(), PHP_EOL);
    }
}

Classes

Your second collection returned could be the list of classes defined in a package, if any.

Reflect returns a list of classes with the getClasses() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $classes = $package->getClasses();
}

This list ($classes) is an iterator, that can be traversed by a simple foreach loop.

Easy exploit classes
<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        echo $class->getName(), PHP_EOL;
    }
}

Interfaces

Your next collection returned could be the list of interfaces defined in a package, if any.

Reflect returns a list of interfaces with the getInterfaces() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $interfaces = $package->getInterfaces();
}

This list ($interfaces) is an iterator, that can be traversed by a simple foreach loop.

Easy exploit interfaces
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getInterfaces() as $interface) {
        echo $interface->getName(), PHP_EOL;
    }
}

Traits

Your next collection returned could be the list of traits defined in a package, if any.

Reflect returns a list of traits with the getTraits() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $traits = $package->getTraits();
}

This list ($traits) is an iterator, that can be traversed by a simple foreach loop.

Easy exploit traits
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getTraits() as $trait) {
        echo $trait->getName(), PHP_EOL;
    }
}

Properties

Your next collection returned could be the list of class properties defined in a package, if any.

Reflect returns a list of class properties with the getProperties() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        printf( 'Processing class "%s" ...' . PHP_EOL, $class->getName() );
        $properties = array();

        foreach ($class->getProperties() as $property) {
            $properties[] = $property->getName();
        }
        printf( 'Properties are : %s' . PHP_EOL, print_r($properties, true) );
    }
}

Parameters

Your next collection returned could be the list of function parameters defined, if any.

Reflect returns a list of function parameters with the getParameters() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        printf( 'Processing class "%s" ...' . PHP_EOL, $class->getName() );

        foreach ($class->getMethods() as $method) {
            $parameters = array();

            foreach ($method->getParameters() as $parameter) {
                $parameters[] = $parameter->getName();
            }
            printf( 'Parameters are : %s' . PHP_EOL, print_r($parameters, true) );
        }
    }
}

Functions

Your next collection returned could be the list of functions defined in a package, if any.

Reflect returns a list of user functions with the getFunctions() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $functions = $package->getFunctions();
}

This list ($functions) is an iterator, that can be traversed by a simple foreach loop.

Easy exploit functions
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getFunctions() as $function) {
        echo $function->getName(), PHP_EOL;
    }
}

Constants

Your next collection returned could be the list of constants defined in a package, if any.

Reflect returns a list of constants with the getConstants() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $constants = $package->getConstants();
}

This list ($constants) is an iterator, that can be traversed by a simple foreach loop.

Easy exploit constants
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getConstants() as $constant) {
        echo $constant->getName(), PHP_EOL;
    }
}

Includes

Your next collection returned could be the list of includes defined in a package, if any.

Reflect returns a list of includes with the getIncludes() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $includes = $package->getIncludes();
}

This list ($includes) is an iterator, that can be traversed by a simple foreach loop.

Easy exploit includes
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getIncludes() as $include) {
        echo $include->getFilePath(), PHP_EOL;
    }
}

Dependencies

Your last collection returned could be the list of dependencies defined in a package, if any.

Reflect returns a list of dependencies with the getDependencies() method.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $dependencies = $package->getDependencies();
}

This list ($dependencies) is an iterator, that can be traversed by a simple foreach loop.

Easy exploit dependencies
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getDependencies() as $dep) {
        echo $dep->getName(), PHP_EOL;
    }
}

Exploit each elements

Packages or Namespaces

The Bartlett\Reflect\Model\PackageModel class reports information about a package/namespace.

Reflect returns a list of packages with the getPackages() method, and each of these elements can be exploited with this PackageModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

$packages = $reflect->getPackages();

This list ($packages) is an iterator, that can be traversed by a simple foreach loop. Each $package element returned is an instance of PackageModel.

Gets an array of element counters
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    $pkgName = $package->getName();
    printf( 'Processing package "%s" ...' . PHP_EOL, $pkgName );

    $counters = array(
        'classes'    => count($package->getClasses()),
        'interfaces' => count($package->getInterfaces()),
        'traits'     => count($package->getTraits()),
        'functions'  => count($package->getFunctions()),
        'constants'  => count($package->getConstants()),
        'includes'   => count($package->getIncludes()),
    );

    printf( 'Metrics : %s' . PHP_EOL, print_r($counters, true) );
}

And lot more. See PackageModel Reference to learn all features and behaviors.

PackageModel Reference is not yet available.

Uses

The Bartlett\Reflect\Model\UseModel class reports information about a use to import a standard namespace or just a constant or function.

Reflect returns a list of use statements with the getUses() method, and each of these elements can be exploited with this UseModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $uses = $package->getUses();
}

This list ($uses) is an iterator, that can be traversed by a simple foreach loop.

Gets an array of use statements
<?php

use Bartlett\Reflect;

$uses = array();

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getUses() as $use) {
        $uses[] = array('name' => $use->getName(), 'alias' => $use->getShortName());
    }
}
print_r($uses);

And lot more. See UseModel Reference to learn all features and behaviors.

UseModel Reference is not yet available.

Classes

The Bartlett\Reflect\Model\ClassModel class reports information about a class, an interface or a trait.

Reflect returns a list of classes with the getClasses() method, and each of these elements can be exploited with this ClassModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $classes = $package->getClasses();
}

This list ($classes) is an iterator, that can be traversed by a simple foreach loop. Each $class element returned is an instance of ClassModel.

Gets an array of methods for the class
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        printf( 'Processing class "%s" ...' . PHP_EOL, $class->getName() );
        $methods = array();

        foreach ($class->getMethods() as $method) {
            $methods[] = $method->getShortName();
        }
        printf( 'Methods are : %s' . PHP_EOL, print_r($methods, true) );
    }
}
Gets an array of constants for the class.
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        printf( 'Processing class "%s" ...' . PHP_EOL, $class->getName() );
        $constants = array();

        foreach ($class->getConstants() as $constant) {
            $constants[ $constant->getShortName() ] = $constant->getValue();
        }
        printf( 'Constants are : %s' . PHP_EOL, print_r($constants, true) );
    }
}
Gets an array of properties for the class
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        printf( 'Processing class "%s" ...' . PHP_EOL, $class->getName() );
        $properties = array();

        foreach ($class->getProperties() as $property) {
            $properties[] = $property->getName();
        }
        printf( 'Properties are : %s' . PHP_EOL, print_r($properties, true) );
    }
}

And lot more. See ClassModel Reference to learn all features and behaviors.

ClassModel Reference is not yet available.

Interfaces

The Bartlett\Reflect\Model\ClassModel class reports information about a class, an interface or a trait.

Reflect returns a list of interfaces with the getInterfaces() method, and each of these elements can be exploited with this ClassModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $interfaces = $package->getInterfaces();
}

This list ($interfaces) is an iterator, that can be traversed by a simple foreach loop. Each $interface element returned is an instance of ClassModel.

Gets an array of methods for the interface
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getInterfaces() as $interface) {
        printf( 'Processing interface "%s" ...' . PHP_EOL, $interface->getName() );
        $methods = array();

        foreach ($interface->getMethods() as $method) {
            $methods[] = $method->getShortName();
        }
        printf( 'Methods are : %s' . PHP_EOL, print_r($methods, true) );
    }
}

And lot more. See ClassModel Reference to learn all features and behaviors.

ClassModel Reference is not yet available.

Traits

The Bartlett\Reflect\Model\ClassModel class reports information about a class, an interface or a trait.

Reflect returns a list of traits with the getTraits() method, and each of these elements can be exploited with this ClassModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $traits = $package->getTraits();
}

This list ($traits) is an iterator, that can be traversed by a simple foreach loop. Each $interface element returned is an instance of ClassModel.

Gets an array of methods for the trait
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getTraits() as $trait) {
        printf( 'Processing trait "%s" ...' . PHP_EOL, $trait->getName() );
        $methods = array();

        foreach ($trait->getMethods() as $method) {
            $methods[] = $method->getShortName();
        }
        printf( 'Methods are : %s' . PHP_EOL, print_r($methods, true) );
    }
}

And lot more. See ClassModel Reference to learn all features and behaviors.

ClassModel Reference is not yet available.

Properties

The Bartlett\Reflect\Model\PropertyModel class reports information about a class property.

Reflect returns a list of class properties with the getProperties() method, and each of these elements can be exploited with this PropertyModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        $properties = $class->getProperties();
    }
}

This list ($properties) is an iterator, that can be traversed by a simple foreach loop. Each $properties element returned is an instance of PropertyModel.

<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        printf( 'Processing class "%s" ...' . PHP_EOL, $class->getName() );
        $properties = array();

        foreach ($class->getProperties() as $property) {
            $properties[] = $property->getName();
        }
        printf( 'Properties are : %s' . PHP_EOL, print_r($properties, true) );
    }
}

PropertyModel Reference is not yet available.

Parameters

The Bartlett\Reflect\Model\ParameterModel class reports information about a function parameter.

Reflect returns a list of function parameters with the getParameters() method, and each of these elements can be exploited with this ParameterModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        foreach ($class->getMethods() as $method) {
            $parameters = $method->getParameters();
        }
    }
}

This list ($parameters) is an iterator, that can be traversed by a simple foreach loop. Each $parameters element returned is an instance of ParameterModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getClasses() as $class) {
        printf( 'Processing class "%s" ...' . PHP_EOL, $class->getName() );

        foreach ($class->getMethods() as $method) {
            $parameters = array();

            foreach ($method->getParameters() as $parameter) {
                $parameters[] = $parameter->getName();
            }
            printf( 'Parameters are : %s' . PHP_EOL, print_r($parameters, true) );
        }
    }
}

ParameterModel Reference is not yet available.

Functions

The Bartlett\Reflect\Model\FunctionModel class reports information about a function.

Reflect returns a list of user functions with the getFunctions() method, and each of these elements can be exploited with this FunctionModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $functions = $package->getFunctions();
}

This list ($functions) is an iterator, that can be traversed by a simple foreach loop. Each $function element returned is an instance of FunctionModel.

Gets an array of functions for the data source
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getFunctions() as $function) {
        printf( 'Processing function "%s" ...' . PHP_EOL, $function->getName() );
        $parameters = array();

        foreach ($function->getParameters() as $parameter) {

            $parameters[] = array(
                'position' => $parameter->getPosition(),
                'optional' => $parameter->isOptional() ? 'YES' : 'NO',
                'name'     => $parameter->getName(),
            );
        }
        printf( 'Parameters are : %s' . PHP_EOL, print_r($parameters, true) );
    }
}

And lot more. See FunctionModel Reference to learn all features and behaviors.

FunctionModel Reference is not yet available.

Constants

The Bartlett\Reflect\Model\ConstantModel class reports information about a constant.

Reflect returns a list of constants with the getConstants() method, and each of these elements can be exploited with this ConstantModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $constants = $package->getConstants();
}

This list ($constants) is an iterator, that can be traversed by a simple foreach loop. Each $constant element returned is an instance of ConstantModel.

Gets an array of constants for the data source
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getConstants() as $constant) {
        printf( 'Processing constant "%s" ...' . PHP_EOL, $constant->getName() );

        if ($constant->isMagic() === true) {
            echo '- Magic constant';
        } else {
            echo '- User constant with value ' . $constant->getValue();
        }
        echo PHP_EOL;
    }
}

And lot more. See ConstantModel Reference to learn all features and behaviors.

ConstantModel Reference is not yet available.

Includes

The Bartlett\Reflect\Model\IncludeModel class reports information about an include.

Reflect returns a list of includes with the getIncludes() method, and each of these elements can be exploited with this IncludeModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $includes = $package->getIncludes();
}

This list ($includes) is an iterator, that can be traversed by a simple foreach loop. Each $include element returned is an instance of IncludeModel.

Gets an array of includes for the data source
<?php

use Bartlett\Reflect;

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getIncludes() as $include) {
        if ($include->isRequire() === true) {
            printf( '- require "%s"', $include->getFilePath() );
        } elseif ($include->isRequireOnce() === true) {
            printf( '- require_once "%s"', $include->getFilePath() );
        } elseif ($include->isInclude() === true) {
            printf( '- include "%s"', $include->getFilePath() );
        } elseif ($include->isIncludeOnce() === true) {
            printf( '- include_once "%s"', $include->getFilePath() );
        }
        echo PHP_EOL;
    }
}

And lot more. See IncludeModel Reference to learn all features and behaviors.

IncludeModel Reference is not yet available.

Dependencies

The Bartlett\Reflect\Model\DependencyModel class reports information about a dependency like class, an interface, a php or extension function.

Reflect returns a list of dependencies with the getDependencies() method, and each of these elements can be exploited with this DependencyModel.

<?php

use Bartlett\Reflect;

$reflect = new Reflect;

foreach ($reflect->getPackages() as $package) {
    $dependencies = $package->getDependencies();
}

This list ($dependencies) is an iterator, that can be traversed by a simple foreach loop. Each $dependency element returned is an instance of DependencyModel.

Gets an array of internal php functions
<?php

use Bartlett\Reflect;

$internalFunctions = array();

foreach ($reflect->getPackages() as $package) {
    foreach ($package->getDependencies() as $dep) {
        $internalFunctions[] = $dep->getName();
    }
}
print_r($internalFunctions);

And lot more. See DependencyModel Reference to learn all features and behaviors.

DependencyModel Reference is not yet available.