воскресенье, 8 марта 2020 г.

Строковые представления типов данных, часть 3

В предыдущих частях (часть 1, часть 2) мы рассмотрели как к строковому типу приводятся скалярные типы данных и null. Сейчас перейдем к таким типам данных как массив, объект и ресурс.

Массив, сразу смотрим пример:

$var = [1,2,3];
$strConcat = 'Эту строку я конкатенирую с переменной ' . $var;
$strEval = "В эту строку я подставляю переменную $var";
echo $var;
echo PHP_EOL;
echo $strConcat;
echo PHP_EOL;
echo $strEval;
// вывод:
Notice: Array to string conversion in file on line ..
Notice: Array to string conversion in file on line ..
Notice: Array to string conversion in file on line ..
Array
Эту строку я конкатенирую с переменной Array
В эту строку я подставляю переменную Array


Итак, строковое представление массива это просто слово Array. И так как это не ожидаемая операция над массивом, то выводится еще и Notice. Таким образом, просто взять и вывести массив на экран не получится. Можно обойти массив с помощью цикла и вывести элементы в нужном формате. Естественно, если элементы тоже массивы - их также требуется обойти циклом. И так далее. В случае если массив одномерный - можно воспользоваться функцией implode. Также, если у вас при вставке в БД в поле появляется слово Array - вы поняли, в чем ошибка.

Объект. С объектами ситуация следующая: не всякий объект можно вывести на экран. Например, возьмем такой класс и попытаемся вывести на экран объект данного класса:

class myStdClass
{
    public $intField;
    public $strField;
}

$var = new myStdClass();
$var->intField = 42;
$var->strField = 'Forty two';
$strConcat = 'Эту строку я конкатенирую с переменной ' . $var;
$strEval = "В эту строку я подставляю переменную $var";
echo $var;
echo PHP_EOL;
echo $strConcat;
echo PHP_EOL;
echo $strEval;
// вывод:
Recoverable fatal error: Object of class stdClass could not be converted to string in ... on line ...


Получаем фатальную ошибку, так как php не представляет как привести данный объект к строковому представлению. Но ситуация поправима. Для приведения к объекта к строке требуется определить в классе "магический" метод __toString. Метод, естественно, должен вернуть некую строку, которая и будет строковым представлением объекта.
Модифицируем класс из предыдущего примера:

class myStdClass
{
    public $intField;
    public $strField;

    public function __toString(): string
    {
        return 'intField: ' . $this->intField . '; strField: ' . $this->strField;
    }
}

$var = new myStdClass();
$var->intField = 42;
$var->strField = 'Forty two';
$strConcat = 'Эту строку я конкатенирую с переменной ' . $var;
$strEval = "В эту строку я подставляю переменную $var";
echo $var;
echo PHP_EOL;
echo $strConcat;
echo PHP_EOL;
echo $strEval;
// вывод:
intField: 42; strField: Forty two
Эту строку я конкатенирую с переменной intField: 42; strField: Forty two
В эту строку я подставляю переменную intField: 42; strField: Forty two


Как видим, теперь наш объект прекрасно приводится к строковому представлению.

Я не знаю ни одного случая, когда требуется строковое представление ресурса. Но для полноты картины посмотрим на следующий код:

$var = fopen('/tmp/1.tmp', 'a');
$strConcat = 'Эту строку я конкатенирую с переменной ' . $var;
$strEval = "В эту строку я подставляю переменную $var";
echo $var;
echo PHP_EOL;
echo $strConcat;
echo PHP_EOL;
echo $strEval;
// вывод:
Resource id #5
Эту строку я конкатенирую с переменной Resource id #5
В эту строку я подставляю переменную Resource id #5


Как видим, толку в этом выводе мало, только убедиться что в переменной хранится ресурс. Надеяться на то, что ИД ресурса (в данном выводе - 5) не изменится при следующем запуске, также не стоит.

На этом я завершаю цикл статей по преобразованию типов данных в строки, всем спасибо за внимание.