How to build classes structure correctly - php

I have this class
class Base
{
// This class contains a lot of private method which are using inside this class
private function CreateRequest()
{
//using curl to send request
}
}
class API_CALLS extend Base
{
//Here i want to create a static class to make API calls to server, but i need to use create request method from base class
static public get_name()
{
$params = array();
$this->CreateRequest($params); // i know this causes the error
}
}
What is the best way to create a class structure in my case?

you must know the meaning of "private","static","$this" in class.
class Base
{
protected static function CreateRequest()
{
//using curl to send request
}
}
class API_CALLS extends Base
{
static function get_name()
{
$params = array();
self::CreateRequest($params);
}
}

Related

Why I get empty object from constructor PHP?

I have two users classes:
class Elastic
{
protected $elastic;
function __construct()
{
$this->elastic = new \Elastica\Client();
}
}
And my second class extends first:
class Map extends Elastic
{
private $mapping;
function __construct($elasticaType)
{
var_dump($this->elastic); die();
}
}
But I get an empty object from $this->elastic. What is wrong with what I'm doing?
You've omitted the call to the parent constructor which contains behavior that you rely on.
class Map extends Elastic
{
private $mapping;
function __construct($elasticaType)
{
parent::__construct();
var_dump($this->elastic); die();
}
}
In PHP (and many other OO languages) a subclass may choose to call the function it's overriding.

PHP hangs on a loop and never makes Request

I have a RESTful API that I need to inteact with using CURL. I have created a wrapper class that has a static function with the CURL code.
class ApiInvoke
{
public static function execute($username, $password, $endpoint, $data = array(), $options = array())
{
//Rest of the CURL code goes here.....
}
}
I the created a class where I call the static APIInvokve class method to actually execute the API call. Below is the consumer class for ApiInvoke class above.
require "api_invoke.php"
class FlowgearConnect
{
//Properties go gere
public function getResults($model, $workflow, $data)
{
$endpoint = $this->getEndpoint($model, $workflow);
$results = array();
if(!is_null($endpoint)){
$results = ApiInvoke::execute('username', 'password', $endpoint, $data array('timeout' => 30));
}
return $results;
}
//....
}
Then I have a ParentClass class that create an instance of FlowgearConnect object which is made avalable to sub-classes. However, all subclasses are are processed inside the same parent class.
class ParentClass
{
private $Flowgear;
public function init()
{
$this->Flowgear = new FlowGearConnect(); //Assuming it has been required somewhere
}
}
Then we may have ChildClassA and ChildClassB which extends ParentClass. By vartue of the child classes extending the parent class they have access to the instance of $this->Flowgear object already because below is how the FlowgearConnect class is used:
class ChildClassA
{
public function getResults()
{
$results = $this->Flowgear->getResults('child_a', 'latestEvents', array());
}
}
ChildClassB has the very same function or rather exact except it might be responsible for getting a list of orders for example.
How these child classes are processed inside the parent class is depicted below:
//A function inside the ParentClass to process ChildClassA and ChildClassB
public function processModules()
{
$modules = $request->getModules();
foreach($modules as $module){
require_once "modules/' . $module;
$Module = new $module();
$Module ->getResults();
}
}
Something along these lines is not right.... Basically the extending class creates an instance of a class that is used by child classes. Somewhere somehow something is not right here and I guess it has everything to do with the facy that I am not using singgleton. I could if I new how to where CURL is concerned.
Stupid of me to ever thought I could never be able to create just one instance of a curl object thanks to Rayhan’s Http Client class (http://raynux.com/blog/2009/06/13/http-client-class-for-php-development/).
Basically what I wanted was to create a CURL SINGLETON class such that I do not have instances of the same object created over and over again.
Below is a skeleton of how I went about to achieve this:
class Flowgear
{
static private $_instance;
//Rest properties here...
public function __cosntsruct()
{ $this->_token = $this->_username .':'. $this->_passoword; }
public function execute()
{
//Call a class that handles the actual API invocation passing all relevant data
}
static public function &getInstance()
{
if(self::$_instance == null){
self::$_instance = new self;
}
return self::$_instance;
}
}
Then I simply get a single instance of the class by calling Flowgear::getInstance();

Overwrite a static method with a non static method

I want to overwrite a static method with a non static method. I'm getting this error:
Fatal error: Cannot make static method Person::say() non static in class Coder on line 22
I want to overwrite a classes parent static method makeCall() with a more specific makeCall() that would be non-static.
Code:
<?php
class Request {
public static function makeCall($url) {
// Do some cURL stuff...
}
}
class API extends Request {
const PRODUCTS = '/products';
private $api;
public function __construct($api) {
$this->api = $api;
}
public function getProducts() {
$this->makeCall(self::PRODUCTS);
}
public function makeCall($service) {
parent::makeCall($this->api . $service);
}
}
I could make the parent makeCall() non-static, but I also want to be able to Request:makeCall() in some places.
You may simply change your methods name. And call it with the new name.
There is no option to have it the same name as a static method of the class you're extending.

PHPUnit: Use Mock to modify return value?

I would like to have a PHPUnit Mock which executes a method like normal, but then modifies the return value in some way before the function returns.
What I have
I have a set of derived classes, similar to below:
abstract class Base
{
abstract protected function getUrl();
public function callUrl() {
$url = $this->getUrl();
// some code to call the URL here
}
}
class Foo extends Base
{
protected function getUrl() {
return "http://www.example.com/Foo";
}
}
class Bar extends Base
{
protected function getUrl() {
return "http://www.example.com/Bar";
}
}
Please note the classes I have are much more complex, and some of the items I have to test have side-effects (such as writing to a database, etc).
The naive, duplicate code approach
If I only had a single derived class (eg; Foo), then I could do the following:
class FooMock extends Foo
{
protected function getUrl() {
return parent::getUrl() . "?sandbox";
}
}
class theTest extends PHPUnit_Framework_TestCase
{
public function testIt() {
$mock = new FooMock();
// assert something
}
}
Unfortunately, this means I would need a specific "Mock" class for each derived class I want to test, all of which perform exactly the same function.
The preferred approach
Instead, I would like to be able to do something like the following:
function callback ($returnValue) {
return $returnValue . "?sandbox";
}
class theTest extends PHPUnit_Framework_TestCase
{
private $mock;
public function testFoo() {
$this->mock = $this->getMockBuilder('Foo')->getMock();
$this->setupMock();
// assert something
}
public function testBar() {
$this->mock = $this->getMockBuilder('Bar')->getMock();
$this->setupMock();
// assert something
}
public function setupMock() {
$this->mock->expects($this->any())
->method('getUrl')
->will($this->postProcessReturnValue('callback'));
}
}
Is this at all possible with PHPUnit?
Update: It was suggested I have an instance of the original class, and an instance of the mock class. Use the original class to get the original return value and modify that. This modified value is then used as the return for the Mock. This is not a feasible way to go about things as the classes are more complex (they have side effects such as writing to the DB).
An example where this would not work;
class Foo extends Base
{
$id = 0;
public function saveToDB() {
$this->id = saveToDBAndReturnId();
}
protected function getUrl() {
if ($this->id > 0) {
return "http://www.example.com/".$this->id;
}
throw new Exception("No ID");
}
}
$foo = new Foo();
$foo->saveToDB();
$url = $foo->getUrl();
Obviously the returned URL would be different between multiple calls. I could always mock saveToDB, but that's starting to feel dirty when all I want to do is post-process the result of getUrl.
PHPUnit allows you to define a stub method that will use a callback to determine what to return.
$this->mock->expects($this->any())
->method('getUrl')
->will($this->returnCallback('callback'));
You can define your callback to call the original class method and modify the return value.
Of course, using mock objects in this way more or less defeats the purpose of having them be "mock" objects, since the mock objects will now rely on the underlying implementation.

When to put factory() method into factoried object and when put factory() method to separated class?

Is it ok to put factory() method to the factoried object's class?
class User {
public static function factory($id) {
return new User($id);
}
private function __construct($id) {
}
}
And when consider placing factory() method into separated class?
class User {
public function __construct($id) {
}
}
class UserFactory {
public static function factory($id) {
return new User($id)
}
}
I can't see any benefits of using additional class for factory, but I consider that there are some benefits I don't know about. :)
When to put factory() method into factoried object and when put factory() method to separated class?
The advantage with putting the factory method inside the class itself is protecting the class from being instantiated without using the factory method:
class User {
public static function factory($id) {
return new User($id);
}
private function __construct($id) {
// Now, only the factory method within this class can call this method.
// (Additionally, this method was static, which it shouldn't.)
}
}
I let other add to this with advantages of the opposite solution.
If you have a static creator method there is not much use in putting in into a factory.
It's only really useful to put factory method in it's own class if it isn't static and you want to inject it somewhere.
class User {
public static function __construct($id) {
}
}
class UserFactory {
public function factory($id) {
return new User($id)
}
}
class SomethingUserReleated {
public function __construct(UserFactory $factory) {
$this->userFactory = $factory;
}
public function iNeedToCreateAnUserForSomething() {
$userOne = $this->userFactory->factory(1233);
$userTwo = $this->userFactory->factory(123533);
}
}
Since you can't to the above with static methods.
Moving the factory methods into separate class allows you to separate object-methods and factory-specific methods (that are only needed while creating a new object).
class User {
public static function __construct($id, $name){
// call this directly or via Factory
}
}
class UserFactory {
private static function randomName(){
// return some random name
}
public static function factory($id){
return new User($id, UserFactory::randomName());
}
}

Categories