PHPStorm: Autocomplete

dakata__92

Super Moderator
Колеги, как да опиша в PHPDoc блок на метод @param array $options ключовете, които може да приеме масива?

Код:
     /**
     * @param array $options
     * @return array
     */
     public function methodName(array $options = [])
     {
     	return $options ;
     }

Търся начин да подобря подсказките на Storm.
Пробвах да въведа примерно:
* @param array $options (key1, key2)
тоест с пояснение, но продължава самото пояснение да не се показва...

 
Хммм ако искаш да фиксираш краен брой възможни ключове, защо не ги изредиш като параметри?

Код:
public function methodName(int $option1, string $option2) {}
 
А можеш и да си направиш така:

Код:
class QueryOptions {
int $option1 = 0;
string $option2 = "default";
// etc

function setOption1(string $val) { $this->option2 = $val; return $this; }
// Boilerplate до дупка
}

$db::all()->fetch(new QueryOptions()->setOption2("another")->setOption1(2));
 
anonimen каза:
Хммм ако искаш да фиксираш краен брой възможни ключове, защо не ги изредиш като параметри?

Код:
public function methodName(int $option1, string $option2) {}

Проблема с изреждането на параметрите е в конкретния случай. Налага ми се да работя в различни моменти с различни конекции към различни бази данни и различни опционалности. Не мога да си позволя даден интерфейсен метод да го заключа по параметри, които в някои случаи не са напълно еднакви. Благодарение на интерфейс уеднаквявам всички методи а в опциите си подавам необходимото.

class QueryOptions {
int $option1 = 0;
string $option2 = "default";
// etc

function setOption1(string $val) { $this->option2 = $val; return $this; }
// Boilerplate до дупка
}

$db::all()->fetch(new QueryOptions()->setOption2("another")->setOption1(2));

Това е вариант, но не знам дали е правилно да извеждам опциите във външен клас само заради autocomplete, а и ще трябва за всеки метод да създавам допълнителен клас.
 
Правилно е да ги изнесеш. Когато става въпрос за обектно-ориентирано програмиране винаги избягвай масивите, когато пренасяш данни. Само ще забатачат кода ти и с нищо няма да го направят по-лесен за разбиране или четене. За това са и DTO-тата.

Всяка база данни има общи и не общи параметри, когато трябва да се направи връзката, и ти ги знаеш какви са.
Направи си едно DTO, което носи тези данни и ги подавай на метода.

Код:
/**
 * @param SomeDto $someDto
 */
public function methodName(SomeDto $someDto)
{
    // your code here
}

Много по-лесно се работи с обекти, а и както казах - е препоръчително.

Зависи как искаш да го структурираш, можеш да го направиш и като ValueObject, но това вече зависи от цялостния ви дизайн.
 
Виж и Psalm (и/или phpstan) - според мен това трябва да е задължителен tool за всеки PHP разработчик.
Иначе съм съгласен с предните коментари за този случай.
 
dakata__92 каза:
Проблема с изреждането на параметрите е в конкретния случай. Налага ми се да работя в различни моменти с различни конекции към различни бази данни и различни опционалности. Не мога да си позволя даден интерфейсен метод да го заключа по параметри, които в някои случаи не са напълно еднакви. Благодарение на интерфейс уеднаквявам всички методи а в опциите си подавам необходимото.
Хммм, нали искаш в анотацията да опишеш всички валидни ключове? Тоест, където описваш класа, имаш цялата информация какви ключове ти трябват…

Ако не го опишеш в аргументите, рискуваш да получиш некоректен вход (масива в аргументите), с който ще трябва да се оправяш вътре в метода.

dakata__92 каза:
Това е вариант, но не знам дали е правилно да извеждам опциите във външен клас само заради autocomplete, а и ще трябва за всеки метод да създавам допълнителен клас.

Ти няма да го правиш заради autocomplete-то, а заради типовите гаранции, които получаваш. Типът на аргумента ти носи гаранция, че подадените данни имат коректния вид. В този случай е практически невъзможно да подадеш 'грешен' вход на първо време, и евентуални грешки от този вид пък ще хващаш по-рано (преди метода).
 
Ще помисля хубаво над думите Ви. Днес ще се пробвам да преимплементирам всичко и ще създам класове с опции за всяка от конекциите. Така ще мога спокойно да връщам инстанцията им.
 

Горе