PHP __callStatic as a factory [closed] - php

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Since __callStatic was introduced in php 5.3, is it a good idea to use it when creating new classes instead of factory method?
For example, $user = Model::User() instead of $user = Model::factory('User'), and then:
public static function __callStatic($name, $arguments)
{
$class_name = 'Model_' . $name;
if( empty($arguments) )
{
return new $class_name();
}
else
{
$reflector = new ReflectionClass($class_name);
return $reflector->newInstanceArgs($arguments);
}
}

This question is heavily opinionated by definition, therefore all I can give is a 'best practice' answer.
Don't. While it's fine that something is possible, you're in practice obfuscating your code. Whoever comes after you to maintain the code will not expect this kind of behavior because it doesn't fit the paradigms taught at any IT education. Your code will be harder to maintain, document and share because you made an unconventional choice that, while perfectly valid and performant, does not offer any benefit over the accepted best practice.
Stick to commonly accepted standards and the developer after you will be thankful.

It seems viable, but you can also make your classes extend a Facade like Laravel do:
class Facade
{
static public function create()
{
if( empty($arguments) )
{
return new static;
}
else
{
$reflector = new ReflectionClass(get_called_class());
return $reflector->newInstanceArgs(func_get_args());
}
}
}
class User extends Facade
{
}
IMHO, the code is more explicit when User::create()

Related

Best way to restrict return value from interface in PHP [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 months ago.
Improve this question
I am developing an open source project in Laravel. I want to create framework which people can create their own payment gateways for their needs by implementing generic interfaces and ui will interact with that payment gateway. Which is the best way restrict return value from interface.
Right now I'm using this technic:
interface PaymentGateway
{
public function savePaymentPlan($email, $name, $surname, $phone, $cardNum, $cardHolderName, $cardExpriy, $amount, $checkoutDay): SavePaymentPlanResult;
}
interface SavePaymentPlanResultInterface{
public function getCardToken();
public function setCardToken($token);
}
class SavePaymentPlanResult implements SavePaymentPlanResultInterface{
private $cardToken = null;
public function setCardToken($token){
$this->cardToken = $token;
}
public function getCardToken(){
return $this->cardToken;
}
}
And using all of them like that:
class StrapiPaymentGateway implements PaymentGateway{
public function savePaymentPlan($email, $name, $surname, $phone, $cardNum, $cardHolderName, $cardExpriy, $amount, $checkoutDay): SavePaymentPlanResult {
$savePaymentPlanResult = new SavePaymentPlanResult;
...
...
$savePaymentPlanResult->setToken('<some-token>')
...
...
return $savePaymentResult;
}
}
Inside controller
class Controller {
test(){
$strapiPaymentGateway = new StrapiPaymentGateway();
$token = $strapiPaymentGateway->getToken();
}
}
Is it true way to do that? Because so many stuff you have to do just restrict return value?
Thanks for your answer.
Yes, defining the return type in the interface is the best way to enforce it.
However, if you want to be strict about coding towards an interface the savePaymentPlan method should return the SavePaymentPlanResultInterface instead of the concrete type. Then again, if you know you will only have one SavePaymentPlanResult, you don't necessarily need the SavePaymentPlanResultInterface.
On a side note: your naming is a bit inconsistent. You seem to add the Interface for interfaces, but then PaymentGateway interface is just called PaymentGateway.

PHP Database class with singleton pattern [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Is it a good practice to create query function inside Database class (which must be created with singletone pattern). Or better create another class with database interface, or something like that, and get database instance in constructor? (Sorry for my English :)
<?php
class Database
{
private static $_pdo = null;
private static function getDatabase() {
if (self::$_pdo === null) {
self::$_pdo = new PDO("mysql:host=localhost;dbname=contact_manager", 'root', '');
}
return self::$_pdo;
}
public static function query($query, $parameters) {
Database::_toArray($parameters);
$query = self::getDatabase()->prepare($query);
$query->execute($parameters);
$result = $query->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
private static function _toArray(&$parameters) {
if (!is_array($parameters)) {
$parameters = array($parameters);
}
}
private function __construct() { }
private function __clone() { }
private function __wakeup() { }
}
?>
This is very wide theme is it good practice or not. As for me there're can be some points of view.
If you don't plan extend your project with another databases which queries should be called via same interface - this solution is OK
If we look at this from SOLID's point of view this is bad decision. According to SOLID you have to separate DB connection from queries. This is because of D-principle (dependency inversion) + S-principle (single responsibility). Also you have to define your own DatabaseInterface which you will use for injection your connection into Repositories - classes which encapsulate your DB queries.
However, this decision also depends on size of your project and your goal. If you just want to make everything right instead of inventing your own brand new bicycle, just take some framework like Symfony or Laravel and forget about this low-level stuff.

What are best practices for using utility functions within PHP classes? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm coming into object-oriented PHP from a more functional Javascript background, so I'm fairly new to both PHP and OOP.
What I'm trying to do is make a class that that is passed the contents of a text file, divides it up into manageable pieces, and then loops over those pieces (steps), and handles them accordingly, sometimes making HTTP requests, sometimes saving chunks of info into a $fileVariables array. Here's a basic outline of what I have:
class Script {
public $file, $client, $fileVariables;
function __construct($file) {
$this->file = $file;
$this->client = new \GuzzleHttp\Client();
$this->fileVariables = array();
}
public function parseAndRun() {
$client = $this->client;
$file = $this->file;
// this is the function that performs the bulk of the class's
// work. It relies on some utility functions that are defined
// after, and are utilized within this function like this:
$steps = $this->divideFileIntoSteps($file);
// or like this:
$this->setVariable($index, $value);
}
public function divideFileIntoSteps($file) {
// return array of file divided into steps
}
public function setVariable($index, $value) {
// push $index => $value into $fileVariables array
}
}
I think it's possible that I'm trying to do something that would be totally okay in functional Javascript, but just feels sloppy in object-oriented PHP. Also, when I run PHPUnit tests on this, I get an error that's something like Serialization of 'Closure' is not allowed, which I think from doing some googling on the error might have something to do with how I'm doing this. Also, the fact that I have to use $this-> over and over again on commonly used functions makes me feel like I'm doing something wrong. It just gives me that bad code feeling.
Is there a better way to do this, bearing in mind that a lot of the functionality has to do with getting and setting items in the $fileVariables array?
Your code is basically correct.
You don't need $file = $this->file;
$this prefix is standard for accessing member functions and variables in PHP.
Your function could look like this:
public function parseAndRun() {
$steps = $this->divideFileIntoSteps($this->file);
// or like this:
$this->setVariable($index, $value);
}
Another best practice is to declare private all methods that you don'n need to access from outside the class. Member variables should all be private and you should have accessor functions for them.

Why use Dependency Injection in this example? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Consider the following code:
class CategoryController
{
private $model;
public function __construct()
{
$this->model = new CategoryModel();
}
}
You will see that Controller depends on the Model. I've heard that doing so is not desirable and Model should be injected instead.
I question why. In my case, I build CategoryModel specifically for CategoryController and I don't see a problem leaving it like this inside the class. I mean, I can't inject SomeOtherModel that's not compatible in there anyway... or can I?
Using Dependency Injection to instead inject it into the Controller seems like waste of code.
Hence, is there any reason to use DI here?
answer
Actually in that example, the big question is what is that for?! No methods just an object holder without any way to get it!?
Yea I know, it's just an example, but thats the problem, in that example you don't need DI, actually you not even need the class at all!
Has #Mark Baker said, without the DI/IoC you can't easily test, since it's tightly cupelled. If you take sometime to read about testing and for this case also Mockery
extra
Using Dependency Injection to instead inject it into the Controller seems like waste of code.
When in cases where you don't have something that does the DI for you, it's easy to allow the objects to pass from constructor or make the default ones, in your example would be something like:
use CategoryModelInterface;
class CategoryController
{
private $model;
public function __construct(CategoryModelInterface $categoty = null)
{
$this->model = $category
? $category
: new CategoryModel();
}
}
This way you don't lose much time, and when/if/maybe you'll do some testing, or change the model completely for another, it's actually possible to do it.
I don't think you'll need DI here. However Mark Baker's comment about testing is valid. But you can get around that by using a getter method for the model. That method can then be mocked in tests:
class CategoryController
{
private $model;
public function __construct()
{
...
}
public function getModel() {
if(!$this->model) {
$this->model = new CategoryModel();
}
return $this->model;
}
}

Laravel is it bad to use public static functions in controllers [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Is it bad to use public static function in laravel controllers
In my Product model I have a function that look like this:
public static function setEndDate($time)
{
if ($time == 2)
{
return Carbon::now()->addMonths(2)->toDateTimeString();
}
else
{
return Carbon::now()->addDays($time)->toDateTimeString();
}
}
And then in my controller I use that function like this:
//Validation etc..
$time = Input::get('end_date'); //To transform end-time
$newProduct = new Product();
$newProduct->some_value = Input::get('some_value');
$newProduct->some_value = Input::get('some_value');
$newProduct->end_date = Product::setEndDate($time); //Using my static function like this
newProduct->save();
Is it bad to use static functions like above?
The question per se is pretty opinion-based. I won't say it's necessarily bad to have methods like these in your model, although I also don't recommend doing it. (For more information about that check out #Colin Schoen's answer)
Anyways, Eloquent offers a much nicer solution for this specific problem of yours: Mutators!
They are kind of "setter methods" in where you can modify or mutate the value that will be assigned to the property. Here's an example:
public function setEndDateAttribute($time){
if ($time == 2)
{
$this->attributes['end_date'] = Carbon::now()->addMonths(2)->toDateTimeString();
}
else
{
$this->attributes['end_date'] = Carbon::now()->addDays($time)->toDateTimeString();
}
}
And you use it like this:
$newProduct->end_date = $time;
There isn't anything that will inherently break when you create static methods, but as in all documentation, it isn't recommended. Why?
Static state is omnipresent and entirely destroys testability since you can't just reset the state. Additionally, anything could affect the state in ways that other aspects of the code can't predict, resulting in the potential for wildly unpredictable behavior.
Laravel 4 prevents this by using static 'facades'. These facades are "syntactic short-hand for IoC resolution". They provide both syntactic sugar and prevent tightly coupled code.
The classes that are resolved by the facades can be changed and allow you to inject mock systems or whatever you wish.

Categories