public static function fields()
 {
     static $fields = [];
     if (!$fields) {
         $func = function () {
             $fields = [];
             if ($data = static::dbQuery('DESCRIBE ' . static::table())) {
                 $fields = array_column($data, 'Field');
             }
             return $fields;
         };
         $fields = App::$debug ? $func() : Cache::get('db:scheme:' . static::table(), $func);
     }
     return $fields;
 }
 /**
  * Получение нескольких записей по ID
  *
  * @param array $ids
  * @return array
  */
 public static function getByIds(array $ids)
 {
     $ids = array_unique($ids);
     // Избавляемся от нуль-ид
     if (false !== ($key = array_search(0, $ids, true))) {
         unset($ids[$key]);
     }
     $Obj = new static();
     $data = [];
     $key_ptrn = static::class . ':%s';
     if ($Obj->is_cacheable) {
         foreach ((array) Cache::get(array_map(function ($item) use($key_ptrn) {
             return sprintf($key_ptrn, $item);
         }, $ids)) as $idx => &$val) {
             $data[$ids[$idx]] = $val;
         }
     }
     // Если есть промахи в кэш
     if (($cache_size = sizeof($data)) !== sizeof($ids)) {
         // Вычисляем разницу для подгрузки
         $missed = array_values($cache_size ? array_diff(array_values($ids), array_keys($data)) : $ids);
         // Подгружаем только не найденные данные,
         // попутно сортируя в порядке ID
         $result = [];
         $diff = $missed ? $Obj->dbGetByIds(static::fields(), $missed) : [];
         foreach ($ids as $id) {
             if (isset($diff[$id])) {
                 Cache::set(sprintf($key_ptrn, $id), $diff[$id]);
             }
             $result[$id] = isset($diff[$id]) ? $diff[$id] : (isset($data[$id]) ? $data[$id] : null);
         }
         $data =& $result;
     }
     $data = array_filter($data);
     array_walk($data, [$Obj, 'prepare']);
     return $data;
 }