I searched around on stackoverflow about the "Using $this when not in object context" but I could't get my answer out of it so I ask it here.
I will just copy my code here so you and me dont get confused:
the error is in this code on the first IF statement($this->checkConnection()):
public function randomLocation() {
if ($this->checkConnection()) {
$fetch = array();
$character = $this->getCharacter($_GET['action']);
$locations = Controller_Core_Database::getObjects('Model_Game_Location');
foreach ($locations as $location) {
$fetchLocation = $location->getLocationNameShort();
$fetch[] = $fetchLocation;
}
$newLocation = rand(0,31);
$character->setLocation($fetch[$newLocation]);
Controller_Core_Database::update($character);
}
}
But I have many functions that begins with this 'checkConnection' and those work, except for this one. which is strange in my opinion(although i'm still a beginner with OOP PHP)
so this is my checkConnection function:
public function checkConnection() {
$mysqli = Controller_Core_Database::getDB();
if ($mysqli != null) {
return TRUE;
} else {
return FALSE;
}
}
the Controller_Core_Database::getDB() code is:
public static function getDB() {
self::$mysqli = new mysqli('','','','');
return self::$mysqli;
}
I have remove the information for security purposes.
And here is a example of a function that works perfectly:
public function createItem() {
$view = new Controller_Core_View();
$view->setViewFile("game/createItem.php");
if ($this->checkConnection()) {
$item = Controller_Core_Database::getObjects('Model_Game_Item');
$enchantment = Controller_Core_Database::getObjects('Model_Game_Itemenchantment');
$view->assign("item", $item);
$view->assign("enchantment", $enchantment);
}
return $view->render();
}
I dont see any different between the 2 functions that works and not works, I hope you can help me
You didn't specified, how randomLocation() method is called.
I supose you are calling that non-static method staticaly - thats why you are not in an object context.
If so, consider rewriting either call to randomLocation() method to use object context - e.i.
$x = new YourObjectName();
$x->randomLocation();
or rewrite checkConnection() method to be static and call it staticaly in randomLocation() method.
Related
I got this function from a question here. when I try on a separate file it runs normally. but when I rewrite it in a class that contains more functions I can rather call it in another file, the searchRec contained in this function (calling the function itself) turns red or is marked as an error by visual studio code. whereas before, above this function I also wrote the same function in which there is a function call itself, and it runs normally.
public function searchRec($haystack, $needle, $pathId=Array(), $pathIndex=Array())
{
foreach($haystack as $index => $item) {
$pathId[] = $item['Id'];
$pathIndex[] = $index;
if($item['Title'] == $needle) {
$returnObject = new stdClass();
$returnObject->match = $item;
$returnObject->pathId = $pathId;
item directly
$returnObject->pathIndex = $pathIndex;
return $returnObject;
}
if(isset($item['Children']) && count($item['Children']>0)) {
(recursively)
$result = searchRec($item['Children'], $needle, $pathId, $pathIndex); //searchRec error, VCS say: undifined function
if($result) {
return $result;
}
}
}
return false;
}
Since it's a class method, you need to call it with object-oriented syntax.
$result = $this->searchRec($item['Children'], $needle, $pathId, $pathIndex);
It doesn't seem to work:
$ref = new ReflectionObject($obj);
if($ref->hasProperty('privateProperty')){
print_r($ref->getProperty('privateProperty'));
}
It gets into the IF loop, and then throws an error:
Property privateProperty does not exist
:|
$ref = new ReflectionProperty($obj, 'privateProperty') doesn't work either...
The documentation page lists a few constants, including IS_PRIVATE. How can I ever use that if I can't access a private property lol?
class A
{
private $b = 'c';
}
$obj = new A();
$r = new ReflectionObject($obj);
$p = $r->getProperty('b');
$p->setAccessible(true); // <--- you set the property to public before you read the value
var_dump($p->getValue($obj));
Please, note that accepted answer will not work if you need to get the value of a private property which comes from a parent class.
For this you can rely on getParentClass method of Reflection API.
Also, this is already solved in this micro-library.
More details in this blog post.
getProperty throws an exception, not an error. The significance is, you can handle it, and save yourself an if:
$ref = new ReflectionObject($obj);
$propName = "myProperty";
try {
$prop = $ref->getProperty($propName);
} catch (ReflectionException $ex) {
echo "property $propName does not exist";
//or echo the exception message: echo $ex->getMessage();
}
To get all private properties, use $ref->getProperties(ReflectionProperty::IS_PRIVATE);
In case you need it without reflection:
public function propertyReader(): Closure
{
return function &($object, $property) {
$value = &Closure::bind(function &() use ($property) {
return $this->$property;
}, $object, $object)->__invoke();
return $value;
};
}
and then just use it (in the same class) like this:
$object = new SomeObject();
$reader = $this->propertyReader();
$result = &$reader($object, 'some_property');
Without reflection, one can also do
class SomeHelperClass {
// Version 1
public static function getProperty1 (object $object, string $property) {
return Closure::bind(
function () use ($property) {
return $this->$property;
},
$object,
$object
)();
}
// Version 2
public static function getProperty2 (object $object, string $property) {
return (
function () use ($property) {
return $this->$property;
}
)->bindTo(
$object,
$object
)->__invoke();
}
}
and then something like
SomeHelperClass::getProperty1($object, $propertyName)
SomeHelperClass::getProperty2($object, $propertyName)
should work.
This is a simplified version of Nikola Stojiljković's answer
It doesn't seem to work:
$ref = new ReflectionObject($obj);
if($ref->hasProperty('privateProperty')){
print_r($ref->getProperty('privateProperty'));
}
It gets into the IF loop, and then throws an error:
Property privateProperty does not exist
:|
$ref = new ReflectionProperty($obj, 'privateProperty') doesn't work either...
The documentation page lists a few constants, including IS_PRIVATE. How can I ever use that if I can't access a private property lol?
class A
{
private $b = 'c';
}
$obj = new A();
$r = new ReflectionObject($obj);
$p = $r->getProperty('b');
$p->setAccessible(true); // <--- you set the property to public before you read the value
var_dump($p->getValue($obj));
Please, note that accepted answer will not work if you need to get the value of a private property which comes from a parent class.
For this you can rely on getParentClass method of Reflection API.
Also, this is already solved in this micro-library.
More details in this blog post.
getProperty throws an exception, not an error. The significance is, you can handle it, and save yourself an if:
$ref = new ReflectionObject($obj);
$propName = "myProperty";
try {
$prop = $ref->getProperty($propName);
} catch (ReflectionException $ex) {
echo "property $propName does not exist";
//or echo the exception message: echo $ex->getMessage();
}
To get all private properties, use $ref->getProperties(ReflectionProperty::IS_PRIVATE);
In case you need it without reflection:
public function propertyReader(): Closure
{
return function &($object, $property) {
$value = &Closure::bind(function &() use ($property) {
return $this->$property;
}, $object, $object)->__invoke();
return $value;
};
}
and then just use it (in the same class) like this:
$object = new SomeObject();
$reader = $this->propertyReader();
$result = &$reader($object, 'some_property');
Without reflection, one can also do
class SomeHelperClass {
// Version 1
public static function getProperty1 (object $object, string $property) {
return Closure::bind(
function () use ($property) {
return $this->$property;
},
$object,
$object
)();
}
// Version 2
public static function getProperty2 (object $object, string $property) {
return (
function () use ($property) {
return $this->$property;
}
)->bindTo(
$object,
$object
)->__invoke();
}
}
and then something like
SomeHelperClass::getProperty1($object, $propertyName)
SomeHelperClass::getProperty2($object, $propertyName)
should work.
This is a simplified version of Nikola Stojiljković's answer
New to OOP, figured I'd practice a bit by sending back data from PHP via ajax. What am I doing wrong here? It works if I change the code to procedural. Here's the OOP:
if (isset($_POST['fruity'])) {
$start_fruity = new Fruity_draft();
$start_fruity->send_json();
}
class Fruity_draft {
public $banned = $_POST['banned'];
public $players = $_POST['players'];
public $random_civs = $_POST['random_civs'];
public $array_list = [];
public $send_json['banned'] = $banned;
function __construct($send_json) {
$this->send_json = $send_json;
}
function send_json() {
echo json_encode($this->send_json);
}
}
First of all, you forgot about passing a parameter to the constructor, it expects an array.
function __construct($send_json) {
In your call, you don't send anything
$start_fruity = new Fruity_draft();
This throws a warning, Warning: Missing Argument 1
and a notice, Notice: Undefined variable: send_json
Second, you should move the initialization of the class variables in the constructor.
class Fruity_draft {
public $banned;
public $players;
public $random_civs;
public $array_list;
public $send_json;
function __construct($send_json) {
$this->banned = 'banned';
$this->players = 'players';
$this->random_civs = 'random_civs';
$this->send_json = $send_json;
$this->send_json['banned'] = $this->banned;
}
...
}
That's not really OOP :). You should return something from the class, not echo.
Also, you should send data from other function to the class.. in the constructor or with a method set_post_data() or something...
Simple:
if (isset($_POST['fruity'])) {
$start_fruity = new Fruity_draft($_POST);
echo $start_fruity->get_json_response();
}
class Fruity_draft {
private $postData;
function __construct($postData) {
$this->postData = $postData;
}
function get_json_response() {
return json_encode($this->postData['banned']);
}
}
I've been writing a test for a simple Datamapper class, and I know the method is working, however the test fails and gives me the error "Fatal error: Call to a member function fetchAll() on a non-object in C:\xampp\htdocs\Call log\tests\model_tests.php on line 13." Obviously, this can't be right, because I can verify that the method works.
Here is the code that it's supposedly erroring on:
function all() {
$calls = $this->pdo->query('SELECT * from calls');
return $calls->fetchAll();
}
Here's my test code:
class TestOfCallMapper extends UnitTestCase {
function testOfReturnsAll() {
$this->createSchema();
$mapper = Callmapper::getInstance();
$results = $mapper->all();
print_r($results);
}
private function createSchema() {
$mapper = CallMapper::getInstance();
$mapper->pdo->exec(file_get_contents('../database/create_schema.sql'));
}
private function destroySchema() {
$mapper = CallMapper::getInstance();
$mapper->pdo->exec(file_get_contents('../database/destroy_schema.sql'));
}
}
$test = new TestOfCallMapper('Test of CallMapper Methods');
$test->run(new HTMLReporter());
If I do this, it works just fine:
$mapper = CallMapper::getInstance();
$test = $mapper->all();
print_r($test->fetchAll());
Your PDO Query is returning false therefore its not and instance of PDO but a boolean, Try something like this!
function all() {
$calls = $this->pdo->query('SELECT * from calls');
if($calls === false)
{
throw new Exception("Unable to perform query");
}
return $calls->fetchAll();
}
and then within your TestOfCallMapper you can do:
function testOfReturnsAll()
{
$this->createSchema();
$mapper = Callmapper::getInstance();
try
{
$results = $mapper->all();
}catch(Exception $e)
{
//Some Logging for $e->getMessage();
return;
}
//Use $results here
}
The pdo query is evidently failing, thus you are trying to call fetchAll on false.
I'd check why it's failing.