include::../description.adoc[]

== Noncompliant Code Example

----
class MyClass
{
    public static $publicstatic = 'Static';
    private static $privatestatic = 'private Static';
    private $private = 'Private';
    private const CONST_PRIVATE = 'Private CONST';
    public $myfield = 42;

    private function __construct() {}
    private function privateMethod() {}
    public function __set($property, $value)  {}
    public function __get($property) {}
}

$clazz = new ReflectionClass('MyClass');

$clazz->getstaticProperties(); // Noncompliant . This gives access to private static properties

$clazz->setStaticPropertyValue('publicstatic', '42'); // OK as there is no overloading to bypass and it respects access control.
$clazz->getStaticPropertyValue('publicstatic'); // OK as there is no overloading to bypass and it respects access control. 

// The following calls can access private or protected constants.
$clazz->getConstant('CONST_PRIVATE'); // Noncompliant. 
$clazz->getConstants(); // Noncompliant. 
$clazz->getReflectionConstant('CONST_PRIVATE'); // Noncompliant.
$clazz->getReflectionConstants(); // Noncompliant.

$obj = $clazz->newInstanceWithoutConstructor(); // Noncompliant. Bypassing private constructor.

$constructor = $clazz->getConstructor();
$constructorClosure = $constructor->getClosure($obj); // Noncompliant. It is possible to call private methods with closures.
$constructor->setAccessible(true); // Noncompliant. Bypassing constructor accessibility.

$prop = new ReflectionProperty('MyClass', 'private');
$prop->setAccessible(true); // Noncompliant. Change accessibility of a property.
$prop->setValue($obj, "newValue"); // Noncompliant. Bypass of the __set method.
$prop->getValue($obj); // Noncompliant. Bypass of the __get method.

$prop2 = $clazz->getProperties()[2];
$prop2->setAccessible(true); // Noncompliant. Change accessibility of a property.
$prop2->setValue($obj, "newValue"); // Noncompliant. Bypass of the __set method.
$prop2->getValue($obj); // Noncompliant. Bypass of the __get method.

$meth = new ReflectionMethod('MyClass', 'privateMethod');
$clos = $meth->getClosure($obj); // Noncompliant. It is possible to call private methods with closures.
$meth->setAccessible(true); // Noncompliant. Change accessibility of a method.

$meth2 = $clazz->getMethods()[0];
$clos2 = $meth2->getClosure($obj); // Noncompliant. It is possible to call private methods with closures.
$meth2->setAccessible(true); // Noncompliant. Change accessibility of a method.

// Using a ReflectionObject instead of the class

$objr = new ReflectionObject($obj);
$objr->newInstanceWithoutConstructor(); // Noncompliant. Bypassing private constructor.

$objr->getStaticPropertyValue("publicstatic"); // OK as there is no overloading to bypass and it respects access control.
$objr->setStaticPropertyValue("publicstatic", "newValue"); // OK as there is no overloading to bypass and it respects access control.

$objr->getStaticProperties(); // Noncompliant. This gives access to private static properties

// The following calls can access private or protected constants.
$objr->getConstant('CONST_PRIVATE'); // Noncompliant.
$objr->getConstants(); // Noncompliant.
$objr->getReflectionConstant('CONST_PRIVATE'); // Noncompliant.
$objr->getReflectionConstants(); // Noncompliant.

$constructor = $objr->getConstructor();
$constructorClosure = $constructor->getClosure($obj); // Noncompliant. It is possible to call private methods with closures.
$constructor->setAccessible(true); // Noncompliant. Bypassing constructor accessibility.

$prop3 = $objr->getProperty('private');
$prop3->setAccessible(true); // Noncompliant. Change accessibility of a property.
$prop3->setValue($obj, "newValue"); // Noncompliant. Bypass of the __set method.
$prop3->getValue($obj); // Noncompliant. Bypass of the __get method.

$prop4 = $objr->getProperties()[2];
$prop4->setAccessible(true); // Noncompliant. Change accessibility of a property.
$prop4->setValue($obj, "newValue"); // Noncompliant. Bypass of the __set method.
$prop4->getValue($obj); // Noncompliant. Bypass of the __get method.

$meth3 = $objr->getMethod('privateMethod');
$clos3 = $meth3->getClosure($obj); // Noncompliant. It is possible to call private methods with closures.
$meth3->setAccessible(true); // Noncompliant. Change accessibility of a method.

$meth4 = $objr->getMethods()[0];
$clos4 = $meth4->getClosure($obj); // Noncompliant. It is possible to call private methods with closures.
$meth4->setAccessible(true); // Noncompliant. Change accessibility of a method.
----

include::../see.adoc[]

ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)

include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]
