Может кто-нибудь объяснить мне, как кажется, что методы класса mysqli имеют свои собственные суб-методы?

Например:

$m = new mysqli('host', 'user', 'pass', 'db');
$q = $m->query('SELECT stuff FROM table');
while ($row = $q->fetch_assoc()) {
// do stuff
}

Как работает query метод в конечном итоге имеет свои собственные «под-методы», такие как fetch_assoc()?

Как я могу повторить это поведение с помощью ООП?

РЕДАКТИРОВАТЬ … будет ли это считаться правильным и / или хорошей практикой?

class MyClass {
function myMethod() {
return new AnotherClass();
}
}

class AnotherClass {
function __construct() {
$this->stuff = 'stuff';
}
}

Тогда я могу сделать:

$obj = new MyClass;
$stuff_getter = $obj->myMethod();
echo $stuff_getter->stuff;

1

Решение

Это немного мнение, основанное на том, что вы спрашиваете, но, поскольку я думаю, что многие люди борются с этим, я предоставлю некоторую общую информацию об этом случае.
Прежде всего, вы не можете сказать, является ли это хорошей практикой или нет. Это зависит от намерения и контекста. Смотрите этот код:

class MyClass {
function myMethod() {
return new AnotherClass();
}
}

Это нормально? Да, это нормально, что вы делаете, но обратите внимание, что у вас есть сильная зависимость здесь. Если вы хотите по какой-то причине иметь разные реализации
из AnotherClass вам нужно изменить код.
Вы можете предотвратить это с помощью внедрения зависимостей. Реализовать интерфейс в AnotherClass и ввести его в MyClass,
Когда у вас есть другая реализация AnotherClass Вы можете просто передать его как «старую» версию.
Как это реализовать, также зависит от цели вашего кода, но я приведу базовый пример вашего кода.

class MyClass {

private $aClass = null;

function __construct($aClass)
{
$this->aClass = $aClass;
}

function myMethod() {
return new $this->aClass();
}
}

interface AnInterface
{

}

class AnotherClass implements AnInterface {
function __construct() {
$this->stuff = 'stuff';
}
}$obj = new MyClass(new AnotherClass());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->stuff;

Теперь, используя это, я могу просто создать другую реализацию AnotherClass и передать его MyClass как я всегда делал. Вместо вашего сценария, где мне нужно добавить еще одну функцию. Например:

class AnotherClass2 implements AnInterface {
function __construct() {
$this->stuff = 'another stuff';
}
}

$obj = new MyClass(new AnotherClass2());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->stuff;

Во-вторых, я замечаю, что вы не определяете переменные. Я думаю, что это немного основано на мнении, но я категорически против публичных переменных (что в вашем случае по умолчанию).
Создайте переменную и назначьте ее в своем конструкторе. Создавайте геттеры и сеттеры (если вы ленивы, вы можете создавать магические геттеры и сеттеры (посмотреть здесь). Вы бы получили что-то вроде этого:

class AnotherClass implements AnInterface {

private $stuff;

function __construct() {
$this->stuff = 'stuff';
}

public function getStuff()
{
return $this->stuff;
}
}

$obj = new MyClass(new AnotherClass());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->getStuff();

Я надеюсь, что это проясняет вашу конструкцию, хотя это может не полностью ответить на ваш вопрос.

Две заметки по этому поводу.

  1. Интерфейс не всегда необходим в PHP, но он, безусловно, является лучшей практикой.
  2. Вместо реализации интерфейса вы также можете использовать структуру наследования, если у вас много дубликатов и, конечно, вам разрешено использовать наследование (это отношение is-a?).

Ваш окончательный код может быть (как пример интерфейса) что-то вроде этого:

class MyClass {

private $aClass = null;

function __construct($aClass)
{
$this->aClass = $aClass;
}

function myMethod() {
return new $this->aClass();
}
}

interface AnInterface
{
public function getStuff();
}

class AnotherClass implements AnInterface {

private $stuff;

function __construct() {
$this->stuff = 'stuff';
}

public function getStuff()
{
return $this->stuff;
}
}

class AnotherClass2 implements AnInterface {

private $stuff;

function __construct() {
$this->stuff = 'another stuff';
}

public function getStuff()
{
return $this->stuff;
}
}$obj = new MyClass(new AnotherClass());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->getStuff();

$obj = new MyClass(new AnotherClass2());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->getStuff();
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]