What About Interfaces Between Components?

What about using interfaces between components and between components and Yii class? I notice components tight bind with each other in Yii2. There is no way to eliminate one component class and create my own new component class instead the old one. I don’t know what methods of one component are used in other components. For User::loginRequired() method in Yii2 there is using of ‘response’ components.


	public function loginRequired()

	{

		$request = Yii::$app->getRequest();

		if (!$request->getIsAjax()) {

			$this->setReturnUrl($request->getUrl());

		}

		if ($this->loginUrl !== null) {

			Yii::$app->getResponse()->redirect($this->loginUrl)->send();

			exit();

		} else {

			throw new HttpException(403, Yii::t('yii', 'Login Required'));

		}

	}

If I create new ‘response’ component I don’t know what methods of ‘response’ component are used in other components.


Yii::$app->getResponse()->redirect($this->loginUrl)->send(); //I don't expect this in 'response' component if I want create my own 'response' component

Now all components dependence with each other.

I propose to create stable interfaces to declare stable methods to component interaction.

For example it is possible to use one stable and more abstract class ResponseInterface which declares rules for interaction with ‘response’ component. So other components will know what methods to use. And ‘response’ component will have to maintain the same interface.


class ResponseInterface

{

	public function __construct($response)

	{

		$this->response=$response;

	}

	public function redirect($url)

	{

		$this->response->redirect($url);

	}

}

I don’t know exactly how realize interfaces and how they must process but they are needed.

Interfaces are needed for all core yii-components. It will be easy to create my own component to substitute any core component. Maybe good interface between components is a simple component getting.




/* This is the simplest interface */

class Interface

{

	public function __construct($component)

	{

		$this->component=$component;

	}

	public function getComponent()

	{

		return $this->component;

	}

}



Do you know about "The Dependency Inversion Principle"? There is good article about resolving the problem wich I encounter in Yii.

Maybe Yii needs refactoring?

The normal way of replacing Yii components would be to not replace it completely but extend the existing class and override its methods to change the behavior. The expected interface for every component is the interface of the default implementation in Yii.

Ok. I understand you. My topic is merely the result of my wish to erase half of the components and substitute them for something better.

Feel free to propose improvements on github issue tracker if you think that something could be done better.

By the way. If something in any component must be changed and this thing is used everywhere outside component what yii team do?

For my own OOP experience this code


Yii::$app->getResponse()->redirect($this->loginUrl)->send();

is worst then


Yii::$app->getResponse()->sendRedirect($this->loginUrl);

This is my notice.

First line allows you to send extra headers while second one doesn’t:




$response = Yii::$app->getResponse()->redirect($this->loginUrl);

$this->getHeaders()->set('MyHeader', $value);

$response->send();



Ok. I agree with you. But Yii::$app->getResponse()->sendRedirect($this->loginUrl); is the wraper to shorten operation and straight way to do thing. For me, yii user, it is more obvious. What I must do to understand how to make straight redirect? Must I read about redirect() method or about ‘response’ component? Yii team must simplify interfaces for users and for self.

In order to learn about how to use it you’ll either check guide or API docs that were actually missing send(). I’ve just fixed it: https://github.com/yiisoft/yii2/commit/45778a4bd7037e2797f29bc80d1c09cedbefffeb Thanks!