diff --git a/app/src/App.php b/app/src/App.php
index a2edeff6..6404f707 100644
--- a/app/src/App.php
+++ b/app/src/App.php
@@ -1,7 +1,5 @@
 <?php
-/**
- * アプリ用の便利関数群
- */
+declare(strict_types=1);
 
 namespace Fc2blog;
 
@@ -15,7 +13,6 @@
 
 class App
 {
-
     /**
      * ブログIDから階層別フォルダ作成
      * @param string $blog_id
@@ -33,7 +30,7 @@ public static function getBlogLayer(string $blog_id): string
      * @param bool $timestamp
      * @return string
      */
-    public static function getUserFilePath(array $file, $abs = false, $timestamp = false): string
+    public static function getUserFilePath(array $file, bool $abs = false, bool $timestamp = false): string
     {
         $file_path = static::getBlogLayer($file['blog_id']) . '/file/' . $file['id'] . '.' . $file['ext'];
         return ($abs ? Config::get('WWW_UPLOAD_DIR') : '/uploads/') . $file_path . ($timestamp ? '?t=' . strtotime($file['updated_at']) : '');
@@ -55,7 +52,7 @@ public static function getThumbnailPath(string $url, int $size = 72, string $whs
         if (!preg_match('{(/uploads/[0-9a-zA-Z]/[0-9a-zA-Z]/[0-9a-zA-Z]/[0-9a-zA-Z]+/file/[0-9]+)\.(png|gif|jpe?g)(\?t=[0-9]+)?$}', $url, $matches)) {
             return $url;
         }
-        return $matches[1] . '_' . $whs . $size . '.' . $matches[2] . (isset($matches[3]) ? $matches[3] : '');
+        return $matches[1] . '_' . $whs . $size . '.' . $matches[2] . ($matches[3] ?? '');
     }
 
     /**
@@ -67,7 +64,7 @@ public static function getThumbnailPath(string $url, int $size = 72, string $whs
      * @param string $whs
      * @return string
      */
-    public static function getCenterThumbnailPath(string $url, $width = 760, $height = 420, $whs = ''): string
+    public static function getCenterThumbnailPath(string $url, int $width = 760, int $height = 420, string $whs = ''): string
     {
         if (empty($url)) {
             return $url;
@@ -75,7 +72,7 @@ public static function getCenterThumbnailPath(string $url, $width = 760, $height
         if (!preg_match('{(/uploads/[0-9a-zA-Z]/[0-9a-zA-Z]/[0-9a-zA-Z]/[0-9a-zA-Z]+/file/[0-9]+)\.(png|gif|jpe?g)(\?t=[0-9]+)?$}', $url, $matches)) {
             return $url;
         }
-        return $matches[1] . '_' . $whs . $width . '_' . $height . '.' . $matches[2] . (isset($matches[3]) ? $matches[3] : '');
+        return $matches[1] . '_' . $whs . $width . '_' . $height . '.' . $matches[2] . ($matches[3] ?? '');
     }
 
     /**
@@ -105,14 +102,14 @@ public static function deleteFile(string $blog_id, string $id): void
      * @param string $id
      * @return string
      */
-    public static function getPluginFilePath(string $blog_id, string $id)
+    public static function getPluginFilePath(string $blog_id, string $id): string
     {
         return Config::get('BLOG_TEMPLATE_DIR') . static::getBlogLayer($blog_id) . '/plugins/' . $id . '.php';
     }
 
     /**
      * ファイルパスまでのフォルダを作成する
-     * @param $file_path
+     * @param string $file_path
      */
     public static function mkdir(string $file_path): void
     {
@@ -167,7 +164,7 @@ public static function calcStartAndEndDate(int $year = 0, int $month = 0, int $d
             $end .= '12-31';
         }
         $dates = explode('-', $start);
-        if (!checkdate($dates[1], $dates[2], $dates[0])) {
+        if (!checkdate((int)$dates[1], (int)$dates[2], (int)$dates[0])) {
             // 存在日付の場合は本日を開始、終了日時として割り当てる
             $start = $end = date('Y-m-d');
         }
@@ -179,9 +176,9 @@ public static function calcStartAndEndDate(int $year = 0, int $month = 0, int $d
     /**
      * デバイスタイプを取得する
      * @param Request $request
-     * @return string|null
+     * @return int
      */
-    public static function getDeviceType(Request $request): string
+    public static function getDeviceType(Request $request): int
     {
         // パラメータによりデバイスタイプを変更(FC2の引数順守)
         if ($request->isArgs('pc')) {
@@ -198,7 +195,7 @@ public static function getDeviceType(Request $request): string
             Config::get('DEVICE_SP'),
         ];
         if (!empty($device_type) && in_array($device_type, $devices)) {
-            return $device_type;
+            return (int)$device_type;
         }
 
         // ユーザーエージェントからデバイスタイプを取得
@@ -321,7 +318,7 @@ public static function userURL(Request $request, array $args = [], bool $reused
             $args = array_merge($gets, $args);
         }
 
-        $controller = $controller = $request->shortControllerName;
+        $controller = $request->shortControllerName;
         if (isset($args['controller'])) {
             $controller = $args['controller'];
             unset($args['controller']);
@@ -366,8 +363,7 @@ public static function userURL(Request $request, array $args = [], bool $reused
             if ($blog_id && $blog_id !== Config::get('DEFAULT_BLOG_ID')) {
                 $url = '/' . $blog_id . $url;
             }
-            $url = ($abs ? $full_domain : '') . $url;
-            return $url;
+            return ($abs ? $full_domain : '') . $url;
         }
 
         // 記事の場合
@@ -388,8 +384,7 @@ public static function userURL(Request $request, array $args = [], bool $reused
             if ($blog_id && $blog_id !== Config::get('DEFAULT_BLOG_ID')) {
                 $url = '/' . $blog_id . $url;
             }
-            $url = ($abs ? $full_domain : '') . $url;
-            return $url;
+            return ($abs ? $full_domain : '') . $url;
         }
 
         $params = [];
@@ -409,14 +404,13 @@ public static function userURL(Request $request, array $args = [], bool $reused
         if ($blog_id && $blog_id !== Config::get('DEFAULT_BLOG_ID')) {
             $url = '/' . $blog_id . $url;
         }
-        $url = ($abs ? $full_domain : '') . $url;
-        return $url;
+        return ($abs ? $full_domain : '') . $url;
     }
 
     /**
      * ページ毎、デバイス毎の初期制限件数
      * @param Request $request
-     * @param $key
+     * @param string $key
      * @return int
      */
     public static function getPageLimit(Request $request, string $key): int
@@ -427,7 +421,7 @@ public static function getPageLimit(Request $request, string $key): int
     /**
      * ページ毎、デバイス毎の件数一覧
      * @param Request $request
-     * @param $key
+     * @param string $key
      * @return array
      */
     public static function getPageList(Request $request, string $key): array
@@ -441,6 +435,7 @@ public static function getPageList(Request $request, string $key): array
      * @param array|string params = array('entries/create', 'entries/edit', ...),
      * @return bool
      * TODO Configの削減
+     * @noinspection PhpUnused
      */
     public static function isActiveMenu(Request $request, $params): bool
     {
diff --git a/app/src/Model/ArrayIterableTrait.php b/app/src/Model/ArrayIterableTrait.php
new file mode 100644
index 00000000..603e1e03
--- /dev/null
+++ b/app/src/Model/ArrayIterableTrait.php
@@ -0,0 +1,69 @@
+<?php
+declare(strict_types=1);
+
+namespace Fc2blog\Model;
+
+use ArrayIterator;
+use Iterator;
+use LogicException;
+use ReflectionClass;
+use ReflectionException;
+
+trait ArrayIterableTrait
+{
+    public static function factory(array $list): ?self
+    {
+        $self = new static();
+        $props = (new ReflectionClass(static::class))->getProperties();
+        foreach ($props as $prop) {
+            $name = $prop->getName();
+            $self->{$name} = $list[$name];
+        }
+        return $self;
+    }
+
+    public function asArray(): array
+    {
+        return (array)$this;
+    }
+
+    // ==== for array access ====
+    public function offsetExists($offset): bool
+    {
+        return isset($this->{$offset});
+    }
+
+    public function offsetGet($offset)
+    {
+        return $this->offsetExists($offset) ? $this->{$offset} : null;
+    }
+
+    public function offsetSet($offset, $value)
+    {
+        $r = new ReflectionClass(static::class);
+        try {
+            $prop = $r->getProperty($offset);
+            if ($prop->isPublic()) {
+                $this->{$prop->getName()} = $value;
+            }
+        } catch (ReflectionException $e) {
+            throw new LogicException("touch missing property " . $e->getMessage());
+        }
+    }
+
+    public function offsetUnset($offset)
+    {
+        throw new LogicException("un-settable.");
+    }
+
+    public function getIterator(): Iterator
+    {
+        return new ArrayIterator((array)$this);
+    }
+
+    public function count(): int
+    {
+        $r = new ReflectionClass(static::class);
+        return count($r->getProperties());
+    }
+}
diff --git a/app/src/Model/Blog.php b/app/src/Model/Blog.php
new file mode 100644
index 00000000..6879cf2a
--- /dev/null
+++ b/app/src/Model/Blog.php
@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace Fc2blog\Model;
+
+use ArrayAccess;
+use Countable;
+use IteratorAggregate;
+
+class Blog implements ArrayAccess, IteratorAggregate, Countable
+{
+    use ArrayIterableTrait;
+
+    public $id;
+    public $user_id;
+    public $name;
+    public $nickname;
+    public $introduction;
+    public $template_pc_id;
+    public $template_sp_id;
+    public $timezone;
+    public $open_status;
+    public $ssl_enable;
+    public $redirect_status_code;
+    public $blog_password;
+    public $trip_salt;
+    public $last_posted_at;
+    public $created_at;
+    public $updated_at;
+}
diff --git a/app/src/Model/BlogPluginsModel.php b/app/src/Model/BlogPluginsModel.php
index 1b869316..204eebc4 100644
--- a/app/src/Model/BlogPluginsModel.php
+++ b/app/src/Model/BlogPluginsModel.php
@@ -36,8 +36,8 @@ public function getAutoIncrementCompositeKey(): string
 
     /**
      * バリデート処理
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
diff --git a/app/src/Model/BlogTemplatesModel.php b/app/src/Model/BlogTemplatesModel.php
index 0400d202..f0738629 100644
--- a/app/src/Model/BlogTemplatesModel.php
+++ b/app/src/Model/BlogTemplatesModel.php
@@ -36,8 +36,8 @@ public function getAutoIncrementCompositeKey(): string
 
     /**
      * バリデート処理
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
@@ -69,7 +69,7 @@ public function validate(array $data, ?array &$valid_data = [], array $white_lis
 
     /**
      * FC2テンプレートの構文チェック
-     * @param $php_code
+     * @param string $php_code
      * @return bool|string
      */
     public static function fc2TemplateSyntax(string $php_code)
@@ -343,9 +343,7 @@ public static function convertFC2Template(string $html)
         // 変数タグの置き換え
         $html = str_replace(Config::get('fc2_template_var_search'), Config::get('fc2_template_var_replace'), $html);
         // 処理されなかった(対応がなかった)変数タグの削除
-        $html = preg_replace('/<%[0-9a-zA-Z_]+?>/', '', $html);
-
-        return $html;
+        return preg_replace('/<%[0-9a-zA-Z_]+?>/', '', $html);
     }
 
     static public function getPathDefaultTemplate(): string
diff --git a/app/src/Model/BlogsModel.php b/app/src/Model/BlogsModel.php
index 8e0b0edf..ecf53491 100644
--- a/app/src/Model/BlogsModel.php
+++ b/app/src/Model/BlogsModel.php
@@ -38,6 +38,7 @@ public function getTableName(): string
      * @param $key
      * @param $data
      * @return bool|string
+     * @noinspection PhpUnusedParameterInspection // $options and $key needs dynamic call
      */
     public static function privateCheck($value, $option, $key, $data)
     {
@@ -60,7 +61,7 @@ public static function privateCheck($value, $option, $key, $data)
      * @param $blog_id
      * @return bool
      */
-    public static function isPasswordRegistered($blog_id)
+    public static function isPasswordRegistered($blog_id): bool
     {
         $blog = (new BlogsModel)->findById($blog_id);
         return (!empty($blog) && strlen($blog['blog_password']) > 0);
@@ -87,8 +88,8 @@ public static function usableDirectory(string $value)
 
     /**
      * バリデート処理
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
@@ -586,9 +587,9 @@ public function deleteByIdAndUserId($blog_id, int $user_id, $options = array())
 
     /**
      * 指定したテンプレートIDが指定したブログIDのデバイステンプレートとして適用されているか判定する
-     * @param $template_id
-     * @param $blog_id
-     * @param $device_type
+     * @param int $template_id
+     * @param string $blog_id
+     * @param int $device_type
      * @return bool
      */
     public function isAppliedTemplate(int $template_id, string $blog_id, int $device_type): bool
@@ -603,8 +604,8 @@ public function isAppliedTemplate(int $template_id, string $blog_id, int $device
 
     /**
      * 指定したブログID,デバイスIDのテンプレートIDを取得する
-     * @param $blog_id
-     * @param $device_type
+     * @param string $blog_id
+     * @param int $device_type
      * @return int
      */
     public function getAppliedTemplateId(string $blog_id, int $device_type): int
@@ -645,10 +646,10 @@ static public function isCorrectHttpSchemaByBlogId(Request $request, string $blo
     /**
      * エントリのパーマリンク
      * @param string $blog_id
-     * @param string $entry_id
+     * @param int $entry_id
      * @return string
      */
-    static public function getEntryFullUrlByBlogIdAndEntryId(string $blog_id, string $entry_id): string
+    static public function getEntryFullUrlByBlogIdAndEntryId(string $blog_id, int $entry_id): string
     {
         $schema = static::getSchemaByBlogId($blog_id);
         $domain = Config::get("DOMAIN");
@@ -659,7 +660,7 @@ static public function getEntryFullUrlByBlogIdAndEntryId(string $blog_id, string
         } else {
             $blog_id_path = "";
         }
-        return $schema . "//" . $domain . $port . $blog_id_path . "/blog-entry-" . (int)$entry_id . ".html";
+        return $schema . "//" . $domain . $port . $blog_id_path . "/blog-entry-" . $entry_id . ".html";
     }
 
     /**
diff --git a/app/src/Model/CategoriesModel.php b/app/src/Model/CategoriesModel.php
index ea65b3f9..9b867355 100644
--- a/app/src/Model/CategoriesModel.php
+++ b/app/src/Model/CategoriesModel.php
@@ -161,7 +161,7 @@ public function getList($blog_id, $options = array())
     {
         $options['where'] = (isset($options['where']) && $options['where'] != '') ? 'blog_id=? AND ' . $options['where'] : 'blog_id=?';
         $options['params'] = isset($options['params']) ? array_merge(array($blog_id), $options['params']) : array($blog_id);
-        $options['order'] = isset($options['order']) ? $options['order'] : 'categories.lft';
+        $options['order'] = $options['order'] ?? 'categories.lft';
         return $this->findNode($options);
     }
 
diff --git a/app/src/Model/CommentsModel.php b/app/src/Model/CommentsModel.php
index b6c2fc80..e86eb181 100644
--- a/app/src/Model/CommentsModel.php
+++ b/app/src/Model/CommentsModel.php
@@ -216,7 +216,7 @@ public function deleteEntryRelation($blog_id, $entry_id)
 
     /**
      * コメントの追加処理 + 記事のコメント数増加処理
-     * @param $request
+     * @param Request $request
      * @param $data
      * @param $blog_setting
      * @return false|int
@@ -412,7 +412,7 @@ public function decorateByBlogSetting(Request $request, $tmp_comments, $blog_set
         $is_add_comment = $blog_setting[Config::get('BLOG_TEMPLATE_REPLY_TYPE_COLUMN.' . $request->deviceType)] == Config::get('BLOG_TEMPLATE.COMMENT_TYPE.AFTER');
 
         $comments = array();
-        foreach ($tmp_comments as $key => $comment) {
+        foreach ($tmp_comments as $comment) {
             if ($self_blog == false) {
                 if ($comment['open_status'] == $flag_pending) {
                     $comment['title'] = '承認待ちです';
diff --git a/app/src/Model/Email.php b/app/src/Model/Email.php
index 9547a0ca..9162e59a 100644
--- a/app/src/Model/Email.php
+++ b/app/src/Model/Email.php
@@ -4,6 +4,7 @@
 namespace Fc2blog\Model;
 
 use Twig\Environment;
+use Twig\Error\Error;
 
 class Email
 {
@@ -14,6 +15,9 @@ class Email
     public $subject;
     public $body;
 
+    /**
+     * @throws Error
+     */
     public function setSubjectAndBodyByTwig(
         Environment $twig,
         string $twig_template,
diff --git a/app/src/Model/EmailLoginTokenService.php b/app/src/Model/EmailLoginTokenService.php
index 40272059..1462fe11 100644
--- a/app/src/Model/EmailLoginTokenService.php
+++ b/app/src/Model/EmailLoginTokenService.php
@@ -8,6 +8,7 @@
 use Fc2blog\Service\TwigService;
 use Fc2blog\Web\Request;
 use RuntimeException;
+use Twig\Error\Error;
 
 class EmailLoginTokenService
 {
@@ -36,6 +37,9 @@ public static function revokeToken(EmailLoginToken $token): void
         $pr_model->deleteById($token->id);
     }
 
+    /**
+     * @throws Error
+     */
     public static function createAndSendToken(Request $request, User $user): bool
     {
         // create token
diff --git a/app/src/Model/EntriesModel.php b/app/src/Model/EntriesModel.php
index 56f96da8..815ce29a 100644
--- a/app/src/Model/EntriesModel.php
+++ b/app/src/Model/EntriesModel.php
@@ -35,8 +35,8 @@ public function getAutoIncrementCompositeKey(): string
 
     /**
      * バリデート処理
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
diff --git a/app/src/Model/EntryCategoriesModel.php b/app/src/Model/EntryCategoriesModel.php
index 25c70811..e4f7b077 100644
--- a/app/src/Model/EntryCategoriesModel.php
+++ b/app/src/Model/EntryCategoriesModel.php
@@ -28,8 +28,8 @@ public function getTableName(): string
 
     /**
      * バリデート処理
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
diff --git a/app/src/Model/EntryTagsModel.php b/app/src/Model/EntryTagsModel.php
index 9225d215..8b4cae7a 100644
--- a/app/src/Model/EntryTagsModel.php
+++ b/app/src/Model/EntryTagsModel.php
@@ -26,8 +26,8 @@ public function getTableName(): string
 
     /**
      * バリデート処理
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
@@ -85,7 +85,7 @@ public function save(string $blog_id, $entry_id, ?array $tags)
             $tags = array();
         }
         $temp_tags = array();
-        foreach ($tags as $key => $tag) {
+        foreach ($tags as $tag) {
             if (is_string($tag) && $tag != '') {
                 // 文字列のみ許可
                 $temp_tags[] = $tag;
diff --git a/app/src/Model/MSDB.php b/app/src/Model/MSDB.php
index 3df8f771..a40b727d 100644
--- a/app/src/Model/MSDB.php
+++ b/app/src/Model/MSDB.php
@@ -1,4 +1,5 @@
-<?php
+<?php /** @noinspection ALL 当面エラーチェックしない */
+
 /**
  * Master/Slaveの切り替え用
  * 基本的にMySqliWrapと同じ機能を有する
diff --git a/app/src/Model/MySqliWrap.php b/app/src/Model/MySqliWrap.php
index fbe71911..8d8cc06f 100644
--- a/app/src/Model/MySqliWrap.php
+++ b/app/src/Model/MySqliWrap.php
@@ -1,4 +1,5 @@
-<?php
+<?php /** @noinspection ALL 当面エラーチェックしない */
+
 /**
  * DB接続クラス
  * mysqliのラッピング
diff --git a/app/src/Model/PDOWrap.php b/app/src/Model/PDOWrap.php
index e0911444..c493afd5 100644
--- a/app/src/Model/PDOWrap.php
+++ b/app/src/Model/PDOWrap.php
@@ -1,4 +1,5 @@
-<?php
+<?php /** @noinspection ALL 当面エラーチェックしない */
+
 /**
  * DB接続クラス
  * mysqliのラッピング
@@ -35,7 +36,7 @@ function __construct($host, $port, $user, $password, $database, $charset)
 
     /**
      * 参照系SQL
-     * @param $sql
+     * @param string $sql
      * @param array $params
      * @param array $options
      * @return mixed
diff --git a/app/src/Model/PasswordResetTokenService.php b/app/src/Model/PasswordResetTokenService.php
index 0b0e0eac..1ca00f86 100644
--- a/app/src/Model/PasswordResetTokenService.php
+++ b/app/src/Model/PasswordResetTokenService.php
@@ -7,6 +7,7 @@
 use Fc2blog\Service\TwigService;
 use Fc2blog\Web\Request;
 use RuntimeException;
+use Twig\Error\Error;
 
 class PasswordResetTokenService
 {
@@ -35,6 +36,9 @@ public static function revokeToken(PasswordResetToken $token): void
         $pr_model->deleteById($token->id);
     }
 
+    /**
+     * @throws Error
+     */
     public static function createAndSendToken(Request $request, User $user): bool
     {
         // create token
diff --git a/app/src/Model/PluginsModel.php b/app/src/Model/PluginsModel.php
index 06ad8fb6..5aa3bc6a 100644
--- a/app/src/Model/PluginsModel.php
+++ b/app/src/Model/PluginsModel.php
@@ -28,8 +28,8 @@ public function getTableName(): string
 
     /**
      * バリデート処理
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
diff --git a/app/src/Model/SystemUpdateModel.php b/app/src/Model/SystemUpdateModel.php
index b61ccfa1..10b8f1b2 100644
--- a/app/src/Model/SystemUpdateModel.php
+++ b/app/src/Model/SystemUpdateModel.php
@@ -273,6 +273,7 @@ public static function updateSystemByLocalZip(string $dist_zip_path)
 
     }
 
+    /** @noinspection PhpReturnValueOfMethodIsNeverUsedInspection */
     private static function rm_r(string $path): bool
     {
         if (!file_exists($path)) return false;
@@ -338,7 +339,6 @@ private static function copy_r(string $src_path, string $dest_dir)
             if (file_exists($dest_full_path) && is_dir($dest_full_path)) {
                 // ディレクトリで、すでにディレクトリが存在しているならスキップ
                 touch($dest_full_path); // update mtime
-                continue;
 
             } else if (!file_exists($dest_full_path) && is_dir($src_full_path)) {
                 // ディレクトリを作成
@@ -364,6 +364,7 @@ private static function copy_r(string $src_path, string $dest_dir)
                 }
                 copy($src_full_path, $dest_full_path);
                 touch($dest_full_path); // update file timestamp
+
             }
         }
     }
diff --git a/app/src/Model/TagsModel.php b/app/src/Model/TagsModel.php
index 1544a181..3b163015 100644
--- a/app/src/Model/TagsModel.php
+++ b/app/src/Model/TagsModel.php
@@ -31,8 +31,8 @@ public function getAutoIncrementCompositeKey(): string
 
     /**
      * バリデート処理(タグの名前更新のみの予定)
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
@@ -102,7 +102,7 @@ public function getSearchList($blog_id)
 
     /**
      * タグ名からタグ情報取得
-     * @param $blog_id
+     * @param string $blog_id
      * @param array $tags
      * @return array
      */
@@ -226,7 +226,7 @@ public function getEntriesTags($blog_id, $entry_ids)
 
     /**
      * 件数を増加させる処理
-     * @param $blog_id
+     * @param string $blog_id
      * @param array $ids
      * @return int|false
      */
diff --git a/app/src/Model/User.php b/app/src/Model/User.php
index 9e386554..6d7f974e 100644
--- a/app/src/Model/User.php
+++ b/app/src/Model/User.php
@@ -4,15 +4,13 @@
 namespace Fc2blog\Model;
 
 use ArrayAccess;
-use ArrayIterator;
 use Countable;
-use Iterator;
 use IteratorAggregate;
-use ReflectionClass;
-use ReflectionException;
 
 class User implements ArrayAccess, IteratorAggregate, Countable
 {
+    use ArrayIterableTrait;
+
     public $id;
     public $login_id;
     public $password;
@@ -21,27 +19,6 @@ class User implements ArrayAccess, IteratorAggregate, Countable
     public $created_at;
     public $logged_at;
 
-    public static function factory($list): ?self
-    {
-        if (!is_array($list)) {
-            return null;
-        }
-        $self = new static();
-        $self->id = $list['id'];
-        $self->login_id = $list['login_id'];
-        $self->password = $list['password'];
-        $self->login_blog_id = $list['login_blog_id'];
-        $self->type = $list['type'];
-        $self->created_at = $list['created_at'];
-        $self->logged_at = $list['logged_at'];
-        return $self;
-    }
-
-    public function asArray(): array
-    {
-        return (array)$this;
-    }
-
     public function setPassword(string $password): void
     {
         $this->password = UsersModel::passwordHash($password);
@@ -51,43 +28,4 @@ public function verifyPassword(string $input_password): bool
     {
         return password_verify($input_password, $this->password);
     }
-
-    // ==== for array access ====
-    public function offsetExists($offset): bool
-    {
-        return isset($this->{$offset});
-    }
-
-    public function offsetGet($offset)
-    {
-        return $this->offsetExists($offset) ? $this->{$offset} : null;
-    }
-
-    public function offsetSet($offset, $value)
-    {
-        $r = new ReflectionClass(static::class);
-        try {
-            $prop = $r->getProperty($offset);
-            if ($prop->isPublic()) {
-                $this->{$prop->getName()} = $value;
-            }
-        } catch (ReflectionException $e) {
-        }
-    }
-
-    public function offsetUnset($offset)
-    {
-        // don't un-settable
-    }
-
-    public function getIterator(): Iterator
-    {
-        return new ArrayIterator((array)$this);
-    }
-
-    public function count(): int
-    {
-        $r = new ReflectionClass(static::class);
-        return count($r->getProperties());
-    }
 }
diff --git a/app/src/Model/UsersModel.php b/app/src/Model/UsersModel.php
index f24dd254..3133d5d8 100644
--- a/app/src/Model/UsersModel.php
+++ b/app/src/Model/UsersModel.php
@@ -55,8 +55,8 @@ private function setValidate($white_list)
 
     /**
      * 登録用のバリデート処理
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
@@ -80,8 +80,8 @@ public function registerValidate(array $data, ?array &$valid_data = [], $white_l
 
     /**
      * 更新用のバリデート
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
@@ -113,8 +113,8 @@ public function updateValidate(array $data, ?array &$valid_data = [], $white_lis
 
     /**
      * ログイン用のバリデート処理
-     * @param $data
-     * @param $valid_data
+     * @param array $data
+     * @param array|null $valid_data
      * @param array $white_list
      * @return array
      */
diff --git a/app/src/Service/BlogService.php b/app/src/Service/BlogService.php
new file mode 100644
index 00000000..c1ec466d
--- /dev/null
+++ b/app/src/Service/BlogService.php
@@ -0,0 +1,18 @@
+<?php
+declare(strict_types=1);
+
+namespace Fc2blog\Service;
+
+use Fc2blog\Model\Blog;
+use Fc2blog\Model\BlogsModel;
+
+class BlogService
+{
+    public static function getById(string $blog_id): ?Blog
+    {
+        $repo = new BlogsModel();
+        $res = $repo->findById($blog_id);
+        if ($res === false) return null;
+        return Blog::factory($res);
+    }
+}
diff --git a/app/src/Service/UserService.php b/app/src/Service/UserService.php
index fa258da4..d685010d 100644
--- a/app/src/Service/UserService.php
+++ b/app/src/Service/UserService.php
@@ -17,7 +17,9 @@ public static function getByLoginId(string $login_id): ?User
     public static function getByLoginIdAndPassword(string $login_id, string $password): ?User
     {
         $repo = new UsersModel();
-        $user = User::factory($repo->findByLoginId($login_id));
+        $row = $repo->findByLoginId($login_id);
+        if ($row === false) return null;
+        $user = User::factory($row);
         return !is_null($user) && $user->verifyPassword($password) ? $user : null;
     }
 
@@ -37,9 +39,7 @@ public static function getById(int $user_id): ?User
     {
         $repo = new UsersModel();
         $res = $repo->findById($user_id);
-
         if ($res === false) return null;
-
         return User::factory($res);
     }
 }
diff --git a/app/src/Util/I18n.php b/app/src/Util/I18n.php
index 4e1f41bf..fea00668 100644
--- a/app/src/Util/I18n.php
+++ b/app/src/Util/I18n.php
@@ -39,7 +39,7 @@ static public function setLanguage(Request $request): string
         }
 
         // 利用できる言語かチェックを兼ねている
-        $request_language = Config::get('LANGUAGES.' . (string)$request_lang); // <== ex: ja_JP.UTF-8
+        $request_language = Config::get('LANGUAGES.' . $request_lang); // <== ex: ja_JP.UTF-8
 
         if (!is_null($request_lang) && !is_null($request_language)) {
             $lang = $request_lang;
diff --git a/app/src/Util/StringCaseConverter.php b/app/src/Util/StringCaseConverter.php
index 27981271..1530a623 100644
--- a/app/src/Util/StringCaseConverter.php
+++ b/app/src/Util/StringCaseConverter.php
@@ -16,8 +16,7 @@ public static function pascalCase(string $snake_case): string
     {
         $snake_case = str_replace('_', ' ', $snake_case);
         $snake_case = ucwords($snake_case);
-        $snake_case = str_replace(' ', '', $snake_case);
-        return $snake_case;
+        return str_replace(' ', '', $snake_case);
     }
 
     /**
diff --git a/app/src/Web/Controller/Admin/AdminController.php b/app/src/Web/Controller/Admin/AdminController.php
index 19aee0c6..db86dd31 100644
--- a/app/src/Web/Controller/Admin/AdminController.php
+++ b/app/src/Web/Controller/Admin/AdminController.php
@@ -6,6 +6,7 @@
 use Fc2blog\Config;
 use Fc2blog\Model\BlogsModel;
 use Fc2blog\Model\UsersModel;
+use Fc2blog\Service\BlogService;
 use Fc2blog\Web\Controller\Controller;
 use Fc2blog\Web\Request;
 use Fc2blog\Web\Session;
@@ -60,7 +61,7 @@ protected function beforeFilter(Request $request)
         }
 
         // ログイン中でかつブログ選択中の場合ブログ情報を取得し時間設定を行う
-        $blog = $this->getBlog($this->getBlogId($request));
+        $blog = BlogService::getById($this->getBlogId($request));
         if (is_array($blog) && isset($blog['timezone'])) {
             date_default_timezone_set($blog['timezone']);
         }
@@ -147,6 +148,7 @@ protected function isAdmin(): bool
      * @param Request $request
      * @return mixed|null
      * // TODO 現在ではrequestが不要なので消し込み
+     * @noinspection PhpUnusedParameterInspection
      */
     protected function getBlogId(Request $request)
     {
@@ -231,17 +233,5 @@ public function error404(): string
         $this->setStatusCode(404);
         return 'admin/common/error404.twig';
     }
-
-    /**
-     * ブログの`http(s)://FQDN(:port)`を生成する
-     * @return string
-     */
-    static public function getHostUrl(): string
-    {
-        $schema = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === "on") ? 'https:' : 'http:';
-        $domain = Config::get("DOMAIN");
-        $port = ($schema === "https:") ? Config::get("HTTPS_PORT_STR") : Config::get("HTTP_PORT_STR");
-        return $schema . "//" . $domain . $port;
-    }
 }
 
diff --git a/app/src/Web/Controller/Admin/BlogPluginsController.php b/app/src/Web/Controller/Admin/BlogPluginsController.php
index 230d6882..7ee29b19 100644
--- a/app/src/Web/Controller/Admin/BlogPluginsController.php
+++ b/app/src/Web/Controller/Admin/BlogPluginsController.php
@@ -32,7 +32,7 @@ public function index(Request $request): string
         $this->set('app_display_hide', Config::get('APP.DISPLAY.HIDE'));
 
         $blog_plugin_json = [];
-        foreach ($category_blog_plugins as $category => $blog_plugins) {
+        foreach ($category_blog_plugins as $blog_plugins) {
             foreach ($blog_plugins as $blog_plugin) {
                 $json[] = array(
                     'id' => $blog_plugin['id'],
@@ -53,7 +53,7 @@ public function index(Request $request): string
      */
     public function official_search(Request $request): string
     {
-        return $this->plugin_search($request, true);
+        return $this->plugin_search($request);
     }
 
     /**
@@ -149,7 +149,7 @@ public function create(Request $request): string
         $errors['blog_plugin'] = $blog_plugins_model->validate($request->get('blog_plugin'), $blog_plugin_data, $white_list);
         if (empty($errors['blog_plugin'])) {
             $blog_plugin_data['blog_id'] = $this->getBlogId($request);
-            if ($id = $blog_plugins_model->insert($blog_plugin_data)) {
+            if ($blog_plugins_model->insert($blog_plugin_data)) {
                 $this->setInfoMessage(__('I created a plugin'));
                 $this->redirect($request, array('action' => 'index', 'device_type' => $blog_plugin_data['device_type']));
             }
@@ -301,7 +301,7 @@ public function plugin_delete(Request $request)
         $user_id = $this->getUserId();
 
         // 削除データの取得
-        if (!$plugin = $plugins_model->findByIdAndUserId($id, $user_id)) {
+        if (!$plugins_model->findByIdAndUserId($id, $user_id)) {
             $this->redirect($request, array('action' => 'search'));
         }
 
@@ -337,7 +337,7 @@ public function download(Request $request)
 
             // 新規登録処理
             $blog_plugin_data['blog_id'] = $this->getBlogId($request);
-            if ($id = Model::load('BlogPlugins')->insert($blog_plugin_data)) {
+            if (Model::load('BlogPlugins')->insert($blog_plugin_data)) {
                 $this->setInfoMessage(__('I created a plugin'));
                 $this->redirect($request, array('action' => 'index', 'device_type' => $plugin['device_type']));
             }
@@ -404,7 +404,7 @@ public function display_change(Request $request)
         $display = $request->get('display') ? Config::get('APP.DISPLAY.SHOW') : Config::get('APP.DISPLAY.HIDE');  // 表示可否
 
         // 編集対象のデータ取得
-        if (!$blog_plugin = $blog_plugins_model->findByIdAndBlogId($id, $blog_id) || !Session::get('sig') || Session::get('sig') !== $request->get('sig')) {
+        if (!$blog_plugins_model->findByIdAndBlogId($id, $blog_id) || !Session::get('sig') || Session::get('sig') !== $request->get('sig')) {
             $this->redirect($request, array('action' => 'index'));
         }
 
@@ -412,35 +412,5 @@ public function display_change(Request $request)
         $blog_plugins_model->updateByIdAndBlogId(array('display' => $display), $id, $blog_id);
 //    $blog_plugins_model->updateDisplay(array($id=>$request->get('display')), $blog_id);   // TODO:後でこちらに置き換え
     }
-
-    /**
-     * テンプレートエクスポート
-     */
-    /*
-      public function export(Request $request)
-      {
-
-        $id = $request->get('id');
-        $blog_id = $this->getBlogId($request);
-
-        // 登録データの取得
-        if (!$blog_plugin=\Fc2blog\Model\Model::load('BlogPlugins')->findByIdAndBlogId($id, $blog_id)) {
-          $this->redirect($request, array('action'=>'index'));
-        }
-
-        $json = array(
-          'title'       => $blog_plugin['title'],
-          'list'        => $blog_plugin['list'],
-          'contents'    => $blog_plugin['contents'],
-          'attribute'   => $blog_plugin['attribute'],
-          'device_type' => $blog_plugin['device_type'],
-        );
-        $json = json_encode($json);
-
-        $this->set('file_name', time() . '.json');
-        $this->set('data', $json);
-        $this->layout = 'download.php';
-      }
-    */
 }
 
diff --git a/app/src/Web/Controller/Admin/BlogSettingsController.php b/app/src/Web/Controller/Admin/BlogSettingsController.php
index 08a7f014..8f947b62 100644
--- a/app/src/Web/Controller/Admin/BlogSettingsController.php
+++ b/app/src/Web/Controller/Admin/BlogSettingsController.php
@@ -38,6 +38,7 @@ public function comment_edit(Request $request): string
      * 記事編集
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function entry_edit(Request $request): string
     {
@@ -52,6 +53,7 @@ public function entry_edit(Request $request): string
      * その他編集
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function etc_edit(Request $request): string
     {
diff --git a/app/src/Web/Controller/Admin/BlogTemplatesController.php b/app/src/Web/Controller/Admin/BlogTemplatesController.php
index 78d48686..41deed24 100644
--- a/app/src/Web/Controller/Admin/BlogTemplatesController.php
+++ b/app/src/Web/Controller/Admin/BlogTemplatesController.php
@@ -50,6 +50,7 @@ public function index(Request $request): string
      * FC2のテンプレート一覧
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function fc2_index(Request $request): string
     {
@@ -79,6 +80,7 @@ public function fc2_index(Request $request): string
      * FC2のテンプレート詳細(スマホ用)
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function fc2_view(Request $request): string
     {
@@ -144,7 +146,7 @@ public function create(Request $request): string
         $errors['blog_template'] = $blog_templates_model->validate($request->get('blog_template'), $blog_template_data, $white_list);
         if (empty($errors['blog_template'])) {
             $blog_template_data['blog_id'] = $this->getBlogId($request);
-            if ($id = $blog_templates_model->insert($blog_template_data)) {
+            if ($blog_templates_model->insert($blog_template_data)) {
                 $this->setInfoMessage(__('I created a template'));
                 $this->redirect($request, ['action' => 'index']);
             }
@@ -224,7 +226,7 @@ public function apply(Request $request)
      * @param Request $request
      * @return string
      */
-    public function download(Request $request)
+    public function download(Request $request): string
     {
         /** @var BlogTemplatesModel $blog_templates_model */
         $blog_templates_model = Model::load('BlogTemplates');
@@ -256,7 +258,7 @@ public function download(Request $request)
         $errors['blog_template'] = $blog_templates_model->validate($blog_template, $blog_template_data, $white_list);
         if (empty($errors['blog_template'])) {
             $blog_template_data['blog_id'] = $this->getBlogId($request);
-            if ($id = $blog_templates_model->insert($blog_template_data)) {
+            if ($blog_templates_model->insert($blog_template_data)) {
                 $this->setInfoMessage('「' . h($blog_template['title']) . '」' . __('I downloaded the template'));
                 $this->redirect($request, array('action' => 'index', 'device_type' => $device_type));
             }
@@ -288,7 +290,7 @@ public function delete(Request $request)
         }
 
         // 削除データの取得
-        if (!$blog_template = $blog_templates_model->findByIdAndBlogId($id, $blog_id)) {
+        if (!$blog_templates_model->findByIdAndBlogId($id, $blog_id)) {
             $this->redirect($request, array('action' => 'index'));
         }
 
diff --git a/app/src/Web/Controller/Admin/BlogsController.php b/app/src/Web/Controller/Admin/BlogsController.php
index 25645e72..a0b7fbac 100644
--- a/app/src/Web/Controller/Admin/BlogsController.php
+++ b/app/src/Web/Controller/Admin/BlogsController.php
@@ -61,7 +61,7 @@ public function create(Request $request): string
         if (empty($errors['blog'])) {
             $blog_data['user_id'] = $this->getUserId();
             $blog_data['trip_salt'] = Base62Proxy::encode(random_bytes(128));
-            if ($id = $blogs_model->insert($blog_data)) {
+            if ($blogs_model->insert($blog_data)) {
                 $this->setInfoMessage(__('I created a blog'));
                 $this->redirect($request, ['action' => 'index']);
             }
@@ -161,14 +161,14 @@ public function delete(Request $request): string
 
         // 削除するブログが存在するか?
         $blogs_model = Model::load('Blogs');
-        if (!$blog = $blogs_model->findByIdAndUserId($blog_id, $user_id)) {
+        if (!$blogs_model->findByIdAndUserId($blog_id, $user_id)) {
             $this->setErrorMessage(__('I failed to remove'));
             $this->redirect($request, ['action' => 'index']);
         }
 
         // 削除処理
         $blogs_model->deleteByIdAndUserId($blog_id, $user_id);
-        $this->setBlog(null); // ログイン中のブログを削除したのでブログの選択中状態を外す
+        $this->setBlog(); // ログイン中のブログを削除したのでブログの選択中状態を外す
         $this->setInfoMessage(__('I removed the blog'));
         $this->redirect($request, ['action' => 'index']);
         return 'admin/blogs/delete.twig'; // 到達しないはずである
diff --git a/app/src/Web/Controller/Admin/CategoriesController.php b/app/src/Web/Controller/Admin/CategoriesController.php
index c7ee9145..261c4b33 100644
--- a/app/src/Web/Controller/Admin/CategoriesController.php
+++ b/app/src/Web/Controller/Admin/CategoriesController.php
@@ -31,7 +31,7 @@ public function create(Request $request): string
 
         // カテゴリ登録数
         $create_limit = Config::get('CATEGORY.CREATE_LIMIT');
-        $is_limit_create_category = ($create_limit > 0) ? ($create_limit <= count($options)) : false;
+        $is_limit_create_category = $create_limit > 0 && $create_limit <= count($options);
         $this->set('is_limit_create_category', $is_limit_create_category);
 
         if ($is_limit_create_category) {
@@ -51,7 +51,7 @@ public function create(Request $request): string
         $errors = $categories_model->validate($category_request, $data, ['parent_id', 'name', 'category_order']);
         if (empty($errors)) {
             $data['blog_id'] = $blog_id;
-            if ($id = $categories_model->addNode($data, 'blog_id=?', [$blog_id])) {
+            if ($categories_model->addNode($data, 'blog_id=?', [$blog_id])) {
                 $this->setInfoMessage(__('I added a category'));
                 $this->redirect($request, ['action' => 'create']);
             }
@@ -126,7 +126,7 @@ public function delete(Request $request)
         }
 
         // 削除データの取得(未分類であるid=1は削除させない)
-        if ($id == 1 || !$category = $categories_model->findByIdAndBlogId($id, $blog_id)) {
+        if ($id == 1 || !$categories_model->findByIdAndBlogId($id, $blog_id)) {
             $this->redirect($request, array('action' => 'create'));
         }
 
@@ -140,6 +140,7 @@ public function delete(Request $request)
      * ajax用のカテゴリ追加 admin/entries/create からインクルード
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function ajax_add(Request $request): string
     {
diff --git a/app/src/Web/Controller/Admin/CommentsController.php b/app/src/Web/Controller/Admin/CommentsController.php
index 55fe3746..2fe03aec 100644
--- a/app/src/Web/Controller/Admin/CommentsController.php
+++ b/app/src/Web/Controller/Admin/CommentsController.php
@@ -165,6 +165,7 @@ public function approval(Request $request)
      * コメントの承認(ajax版)
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function ajax_approval(Request $request): string
     {
@@ -203,6 +204,7 @@ public function ajax_approval(Request $request): string
      * 返信
      * @param Request $request
      * @return string
+     * @noinspection PhpMissingReturnTypeInspection
      */
     public function reply(Request $request)
     {
@@ -261,6 +263,7 @@ public function reply(Request $request)
      * ajax用の返信
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function ajax_reply(Request $request): string
     {
diff --git a/app/src/Web/Controller/Admin/CommonController.php b/app/src/Web/Controller/Admin/CommonController.php
index b2b86f72..2630d358 100644
--- a/app/src/Web/Controller/Admin/CommonController.php
+++ b/app/src/Web/Controller/Admin/CommonController.php
@@ -24,7 +24,7 @@ public function lang(Request $request)
     {
         // 言語の設定
         $lang = $request->get('lang');
-        if ($language = Config::get('LANGUAGES.' . $lang)) {
+        if (Config::get('LANGUAGES.' . $lang)) {
             Cookie::set($request, 'lang', $lang);
         }
 
@@ -40,6 +40,7 @@ public function lang(Request $request)
     /**
      * デバイス変更
      * @param Request $request
+     * @noinspection PhpUnused
      */
     public function device_change(Request $request)
     {
@@ -96,7 +97,7 @@ public function index(Request $request)
      * @param Request $request
      * @return string
      */
-    public function notice(Request $request)
+    public function notice(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
 
@@ -129,6 +130,7 @@ public function install(Request $request): string
                 $this->set('temp_dir', Config::get('TEMP_DIR'));
                 $this->set('www_upload_dir', Config::get('WWW_UPLOAD_DIR'));
                 $this->set('is_db_connect_lib', defined('DB_CONNECT_LIB'));
+            /** @noinspection PhpRedundantOptionalArgumentInspection */
                 $this->set('random_string', App::genRandomStringAlphaNum(32));
 
                 $this->set('DB_HOST', DB_HOST);
@@ -228,8 +230,7 @@ public function install(Request $request): string
                 }
                 $res = MSDB::getInstance()->multiExecute($sql);
                 if ($res === false) {
-                    /** @noinspection SyntaxError */
-                    $this->setErrorMessage(__('Create table failed.'));
+                    $this->setErrorMessage(__('Create' . ' table failed.'));
                     $this->redirect($request, $request->baseDirectory . 'common/install?state=0&error=table_insert');
                 }
 
@@ -237,8 +238,7 @@ public function install(Request $request): string
                 $sql = "SHOW TABLES LIKE 'users'";
                 $table = MSDB::getInstance()->find($sql);
                 if (!is_countable($table)) {
-                    /** @noinspection SyntaxError */
-                    $this->setErrorMessage(__('Create table failed.'));
+                    $this->setErrorMessage(__('Create' . ' table failed.'));
                     $this->redirect($request, $request->baseDirectory . 'common/install?state=0&error=table_insert');
                 }
 
diff --git a/app/src/Web/Controller/Admin/EntriesController.php b/app/src/Web/Controller/Admin/EntriesController.php
index 6713b802..c1042dbb 100644
--- a/app/src/Web/Controller/Admin/EntriesController.php
+++ b/app/src/Web/Controller/Admin/EntriesController.php
@@ -295,8 +295,9 @@ public function delete(Request $request)
      * ajaxでメディアを表示する画面
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
-    public function ajax_media_load(Request $request)
+    public function ajax_media_load(Request $request): string
     {
         if ($this->isInvalidAjaxRequest($request)) {
             return $this->error403();
diff --git a/app/src/Web/Controller/Admin/FilesController.php b/app/src/Web/Controller/Admin/FilesController.php
index 9832f1b7..9b6bfcb9 100644
--- a/app/src/Web/Controller/Admin/FilesController.php
+++ b/app/src/Web/Controller/Admin/FilesController.php
@@ -16,6 +16,7 @@ class FilesController extends AdminController
      * 一覧表示 /admin/files/upload からPartial読み込み
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function ajax_index(Request $request): string
     {
@@ -218,7 +219,7 @@ public function edit(Request $request): string
         $errors = [];
         $errors['file'] = $files_model->updateValidate($request->file('file'), $request->get('file'), $file, $data_file);
         if (empty($errors['file'])) {
-            $tmp_name = isset($data_file['tmp_name']) ? $data_file['tmp_name'] : null;
+            $tmp_name = $data_file['tmp_name'] ?? null;
             unset($data_file['tmp_name']);
             if ($files_model->updateByIdAndBlogId($data_file, $id, $blog_id)) {
                 // ファイルの移動
@@ -281,6 +282,7 @@ public function delete(Request $request)
      * 削除
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function ajax_delete(Request $request): string
     {
@@ -303,6 +305,7 @@ public function ajax_delete(Request $request): string
      * ajaxによるファイルアップロード受付
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused
      */
     public function ajax_file_upload(Request $request): string
     {
diff --git a/app/src/Web/Controller/Admin/PasswordResetController.php b/app/src/Web/Controller/Admin/PasswordResetController.php
index 59d53ec3..48d34172 100644
--- a/app/src/Web/Controller/Admin/PasswordResetController.php
+++ b/app/src/Web/Controller/Admin/PasswordResetController.php
@@ -7,9 +7,11 @@
 use Fc2blog\Model\PasswordResetTokenService;
 use Fc2blog\Service\UserService;
 use Fc2blog\Web\Request;
+use Twig\Error\Error;
 
 class PasswordResetController extends AdminController
 {
+    /** @noinspection PhpUnused */
     public function requestForm(Request $request): string
     {
         // 未ログインだとSigが生成されていないため、ここで生成する。
@@ -33,15 +35,19 @@ public function request(Request $request): string
         if (!is_null($user = UserService::getByLoginId($login_id))) {
             if (defined("EMERGENCY_PASSWORD_RESET_ENABLE") && EMERGENCY_PASSWORD_RESET_ENABLE === "1") {
                 // Show password reset form directly when EMERGENCY_PASSWORD_RESET_ENABLE is "1".
-                // This is a emergency feature for Unable to send mail enviroment.
+                // This is a emergency feature for Unable to send mail environment.
                 $token = PasswordResetToken::factoryWithUser($user);
                 PasswordResetTokenService::create($token);
                 $this->set('token', $token->token);
                 return 'admin/password_reset/reset_form.twig';
             }
 
-            $result = PasswordResetTokenService::createAndSendToken($request, $user);
-            if ($result === false) {
+            try {
+                $result = PasswordResetTokenService::createAndSendToken($request, $user);
+                if ($result === false) {
+                    return 'admin/password_reset/mail_sending_error.twig';
+                }
+            } catch (Error $e) {
                 return 'admin/password_reset/mail_sending_error.twig';
             }
         }
@@ -52,6 +58,7 @@ public function request(Request $request): string
         return 'admin/password_reset/requested.twig';
     }
 
+    /** @noinspection PhpUnused */
     public function resetForm(Request $request): string
     {
         $token_str = $request->get('token');
diff --git a/app/src/Web/Controller/Admin/SessionController.php b/app/src/Web/Controller/Admin/SessionController.php
index 5352b926..4addfdf9 100644
--- a/app/src/Web/Controller/Admin/SessionController.php
+++ b/app/src/Web/Controller/Admin/SessionController.php
@@ -8,6 +8,7 @@
 use Fc2blog\Service\UserService;
 use Fc2blog\Web\Request;
 use Fc2blog\Web\Session;
+use Twig\Error\Error;
 
 class SessionController extends AdminController
 {
@@ -66,8 +67,12 @@ public function doLogin(Request $request): string
         // MFA処理
         if (Config::get('MFA_EMAIL') === "1") {
             // create and send login mail
-            if (false === EmailLoginTokenService::createAndSendToken($request, $user)) {
-                return "admin/email_login/mail_sending_error.twig";
+            try {
+                if (false === EmailLoginTokenService::createAndSendToken($request, $user)) {
+                    return "admin/email_login/mail_sending_error.twig";
+                }
+            } catch (Error $e) {
+                return 'admin/email_login/mail_sending_error.twig';
             }
             // MFA必須の場合はメール経由でmailLogin()へ
             return "admin/email_login/requested.twig";
diff --git a/app/src/Web/Controller/Admin/SystemUpdateController.php b/app/src/Web/Controller/Admin/SystemUpdateController.php
index 489fcb50..5646d33d 100644
--- a/app/src/Web/Controller/Admin/SystemUpdateController.php
+++ b/app/src/Web/Controller/Admin/SystemUpdateController.php
@@ -10,6 +10,7 @@
 
 class SystemUpdateController extends AdminController
 {
+    /** @noinspection PhpUnusedParameterInspection */
     public function index(Request $request): string
     {
         // TODO unit test
diff --git a/app/src/Web/Controller/Admin/UsersController.php b/app/src/Web/Controller/Admin/UsersController.php
index 77f28446..25876e77 100644
--- a/app/src/Web/Controller/Admin/UsersController.php
+++ b/app/src/Web/Controller/Admin/UsersController.php
@@ -16,7 +16,7 @@ class UsersController extends AdminController
      * @param Request $request
      * @return string
      */
-    public function index(Request $request)
+    public function index(Request $request): string
     {
         if (!$this->isAdmin()) {
             return $this->error404();
@@ -67,7 +67,7 @@ public function register(Request $request)
         $errors['blog'] = $blogs_model->validate($request->get('blog'), $blog_data, array('id', 'name', 'nickname'));
         if (empty($errors['user']) && empty($errors['blog'])) {
             $blog_data['user_id'] = $users_model->insert($user_data);
-            if ($blog_data['user_id'] && $blog_id = $blogs_model->insert($blog_data)) {
+            if ($blog_data['user_id'] && $blogs_model->insert($blog_data)) {
                 $this->setInfoMessage(__('User registration is completed'));
                 $this->redirect($request, array('action' => 'login'));
             } else {
@@ -126,6 +126,7 @@ public function edit(Request $request): string
      * 退会
      * @param Request $request
      * @return string
+     * @noinspection PhpUnused called dynamic
      */
     public function withdrawal(Request $request): string
     {
diff --git a/app/src/Web/Controller/Controller.php b/app/src/Web/Controller/Controller.php
index 1f52ff67..86b7a6c4 100644
--- a/app/src/Web/Controller/Controller.php
+++ b/app/src/Web/Controller/Controller.php
@@ -1,7 +1,5 @@
 <?php
-/**
- * Controllerの親クラス
- */
+declare(strict_types=1);
 
 namespace Fc2blog\Web\Controller;
 
@@ -19,15 +17,14 @@
 use InvalidArgumentException;
 use LogicException;
 use RuntimeException;
-use Twig\Error\LoaderError;
-use Twig\Error\RuntimeError;
-use Twig\Error\SyntaxError;
+use Twig\Error\Error;
 
 abstract class Controller
 {
-    protected $data = [
+    /** @var array<string, mixed> */
+    protected $data = [ // テンプレートへ渡す変数の保存領域
         'http_status_code' => 200
-    ];    // テンプレートへ渡す変数の保存領域
+    ];
     protected $layout = '';  // 表示ページのレイアウトテンプレート
     protected $output = '';  // 送信するデータ、HTML等
     private $resolvedMethod;
@@ -42,7 +39,7 @@ public function __construct(Request $request)
         $this->request = $request;
     }
 
-    public function execute($method)
+    public function execute($method): void
     {
         $template = $this->prepare($method);
         $this->render($template);
@@ -57,8 +54,9 @@ public function prepare(string $method): string
     {
         $this->beforeFilter($this->request);
 
-        // アクションの実行(返り値はテンプレートファイルパスまたは空文字、レンダリング用データは$this->data)
         $this->resolvedMethod = $method;
+
+        // アクションの実行(返り値はテンプレートファイルパスまたは空文字、レンダリング用データは$this->data)
         $template_path = $this->$method($this->request);
 
         // 空の場合は、規約に則ってテンプレートファイルを決定する
@@ -116,7 +114,7 @@ protected function isInvalidAjaxRequest(Request $request): bool
         # ORIGINを検証
         if (
             isset($request->server['HTTP_ORIGIN']) &&
-            $request->server['HTTP_ORIGIN'] !== AdminController::getHostUrl()
+            $request->server['HTTP_ORIGIN'] !== Controller::getHostUrl()
         ) {
             return true;
         }
@@ -144,7 +142,7 @@ public function set(string $key, $value)
      * @param string|null $blog_id
      * @throws RedirectExit
      */
-    protected function redirect(Request $request, $url, $hash = '', bool $full_url = false, string $blog_id = null)
+    protected function redirect(Request $request, $url, string $hash = '', bool $full_url = false, string $blog_id = null)
     {
         if (is_array($url)) {
             $url = Html::url($request, $url, false, $full_url);
@@ -189,7 +187,7 @@ protected function redirect(Request $request, $url, $hash = '', bool $full_url =
      * @param $url
      * @param string $hash
      */
-    protected function redirectBack(Request $request, $url, $hash = '')
+    protected function redirectBack(Request $request, $url, string $hash = '')
     {
         // 元のURLに戻す
         if (!empty($request->server['HTTP_REFERER'])) {
@@ -267,11 +265,7 @@ private function renderByTwig(Request $request, string $twig_template): string
 
         try {
             return $twig->render($twig_template_path, $data);
-        } catch (LoaderError $e) {
-            throw new RuntimeException("Twig error: {$e->getMessage()} {$e->getFile()}:{$e->getTemplateLine()}");
-        } catch (RuntimeError $e) {
-            throw new RuntimeException("Twig error: {$e->getMessage()} {$e->getFile()}:{$e->getTemplateLine()}");
-        } catch (SyntaxError $e) {
+        } catch (Error $e) {
             throw new RuntimeException("Twig error: {$e->getMessage()} {$e->getFile()}:{$e->getTemplateLine()}");
         }
     }
@@ -340,6 +334,8 @@ static public function preprocessingDataForFc2Template(Request $request, array $
                 $data['comments'][$key]['wayoubi'] = __($data['comments'][$key]['youbi']);
                 $data['comments'][$key]['body'] = $value['body']; // TODO nl2brされていないのは正しいのか?
 
+                $value['reply_updated_at'] = $value['reply_updated_at'] ?? ""; // reply_updated_at is nullable
+                $reply_updated_at = strtotime($value['reply_updated_at']) ?: 0;
                 [
                     $data['comments'][$key]['reply_year'],
                     $data['comments'][$key]['reply_month'],
@@ -348,9 +344,9 @@ static public function preprocessingDataForFc2Template(Request $request, array $
                     $data['comments'][$key]['reply_minute'],
                     $data['comments'][$key]['reply_second'],
                     $data['comments'][$key]['reply_youbi']
-                ] = explode('/', date('Y/m/d/H/i/s/D', strtotime($value['reply_updated_at'])));
+                ] = explode('/', date('Y/m/d/H/i/s/D', $reply_updated_at));
                 $data['comments'][$key]['reply_wayoubi'] = __($data['comments'][$key]['reply_youbi']);
-                $data['comments'][$key]['reply_body'] = nl2br($value['reply_body']);
+                $data['comments'][$key]['reply_body'] = nl2br((string)$value['reply_body']);
             }
         }
 
@@ -379,7 +375,7 @@ static public function preprocessingDataForFc2Template(Request $request, array $
      * @return string
      * TODO User系のみで用いられるので、後日UserControllerへ移動
      */
-    private function renderByFc2Template(Request $request, string $template_file_path)
+    private function renderByFc2Template(Request $request, string $template_file_path): string
     {
         if (is_null($template_file_path)) {
             throw new InvalidArgumentException("undefined template");
@@ -400,34 +396,38 @@ private function renderByFc2Template(Request $request, string $template_file_pat
         return ob_get_clean();
     }
 
-    // 存在しないアクションは404へ
-    // TODO 存在しないメソッドコールはエラーにしたほうがわかりやすい
-    public function __call($name, $arguments)
+    // 存在しないアクションはエラーとして404へ
+    // TODO 「アクションではない」メソッドがたたけないようにする。アクション以外を追い出すかシグネチャを見るか。
+    public function __call($name, $arguments): string
     {
         return $this->error404();
     }
 
     // 404 NotFound Action
-    public function error404()
+    public function error404(): string
     {
         $this->setStatusCode(404);
         return 'user/common/error404.twig';
     }
 
     // 403 Forbidden
-    public function error403()
+    public function error403(): string
     {
         $this->setStatusCode(403);
         return 'user/common/error403.twig';
     }
 
     // 400 BadRequest
-    public function error400()
+    public function error400(): string
     {
         $this->setStatusCode(400);
         return 'user/common/error400.twig';
     }
 
+    /**
+     * @param string $key
+     * @return mixed
+     */
     public function get(string $key)
     {
         return $this->data[$key];
@@ -483,7 +483,7 @@ public function getData(): array
     /**
      * blog_idからブログ情報を取得
      * @param $blog_id
-     * @return array|false|mixed
+     * @return array|false
      * @deprecated TODO Modelに移動するべき
      */
     public function getBlog($blog_id)
@@ -493,10 +493,10 @@ public function getBlog($blog_id)
 
     /**
      * デバイスタイプを取得する
-     * @return string
+     * @return int
      * @deprecated TODO requestに置換できる
      */
-    protected function getDeviceType(): string
+    protected function getDeviceType(): int
     {
         return $this->request->deviceType;
     }
@@ -507,11 +507,11 @@ protected function getDeviceType(): string
      * @param string $name
      * TODO captchaでしかつかっていないので、名前をかえるべき
      */
-    protected function setToken($key = null, $name = 'token'): void
+    protected function setToken($key = null, string $name = 'token'): void
     {
         if ($key === null) {
             // 適当な値をトークンに設定
-            $key = App::genRandomStringAlphaNum(32);
+            $key = App::genRandomStringAlphaNum();
         }
         Session::set($name, $key);
     }
@@ -523,11 +523,22 @@ protected function setToken($key = null, $name = 'token'): void
      * @return string|null
      * TODO captchaでしかつかっていないので、名前をかえるべき
      */
-    protected function tokenValidate(Request $request, $name = 'token')
+    protected function tokenValidate(Request $request, string $name = 'token'): ?string
     {
         $value = $request->get($name, '');
         $value = mb_convert_kana($value, 'n');
         return Session::remove($name) == $value ? null : __('Token authentication is invalid');
     }
 
+    /**
+     * ブログの`http(s)://FQDN(:port)`を生成する
+     * @return string
+     */
+    static public function getHostUrl(): string
+    {
+        $schema = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === "on") ? 'https:' : 'http:';
+        $domain = Config::get("DOMAIN");
+        $port = ($schema === "https:") ? Config::get("HTTPS_PORT_STR") : Config::get("HTTP_PORT_STR");
+        return $schema . "//" . $domain . $port;
+    }
 }
diff --git a/app/src/Web/Controller/User/BlogsController.php b/app/src/Web/Controller/User/BlogsController.php
index be1bbcd4..2d3a1767 100644
--- a/app/src/Web/Controller/User/BlogsController.php
+++ b/app/src/Web/Controller/User/BlogsController.php
@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace Fc2blog\Web\Controller\User;
 
diff --git a/app/src/Web/Controller/User/CommonController.php b/app/src/Web/Controller/User/CommonController.php
index d798b2cf..a3066e94 100644
--- a/app/src/Web/Controller/User/CommonController.php
+++ b/app/src/Web/Controller/User/CommonController.php
@@ -23,7 +23,7 @@ public function lang(Request $request)
     {
         // 言語の設定
         $lang = $request->get('lang');
-        if ($language = Config::get('LANGUAGES.' . $lang)) {
+        if (Config::get('LANGUAGES.' . $lang)) {
             Cookie::set($request, 'lang', $lang);
         }
 
diff --git a/app/src/Web/Controller/User/EntriesController.php b/app/src/Web/Controller/User/EntriesController.php
index ac618425..3112b49b 100644
--- a/app/src/Web/Controller/User/EntriesController.php
+++ b/app/src/Web/Controller/User/EntriesController.php
@@ -13,6 +13,7 @@
 use Fc2blog\Model\EntriesModel;
 use Fc2blog\Model\Model;
 use Fc2blog\Model\TagsModel;
+use Fc2blog\Service\BlogService;
 use Fc2blog\Util\Log;
 use Fc2blog\Web\Request;
 use Fc2blog\Web\Session;
@@ -22,12 +23,11 @@
 
 class EntriesController extends UserController
 {
-
     /**
      * 記事系統の前処理
      * @param Request $request
      */
-    protected function beforeFilter(Request $request)
+    protected function beforeFilter(Request $request): void
     {
         parent::beforeFilter($request);
 
@@ -84,7 +84,7 @@ protected function beforeFilter(Request $request)
      * @param Request $request
      * @return string
      */
-    public function index(Request $request)
+    public function index(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
         if (!$blog_id) {
@@ -108,7 +108,7 @@ public function index(Request $request)
      * @param Request $request
      * @return string
      */
-    public function search(Request $request)
+    public function search(Request $request): string
     {
         $where = 'blog_id=?';
         $params = array($this->getBlogId($request));
@@ -135,7 +135,7 @@ public function search(Request $request)
      * @param Request $request
      * @return string
      */
-    public function category(Request $request)
+    public function category(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
         $category_id = $request->get('cat');
@@ -169,7 +169,7 @@ public function category(Request $request)
      * @param Request $request
      * @return string
      */
-    public function tag(Request $request)
+    public function tag(Request $request): string
     {
         // タグ検索
         $blog_id = $this->getBlogId($request);
@@ -202,7 +202,7 @@ public function tag(Request $request)
      * @param Request $request
      * @return string
      */
-    public function date(Request $request)
+    public function date(Request $request): string
     {
         // 開始日付と終了日付の計算
         preg_match('/^([0-9]{4})([0-9]{2})?([0-9]{2})?$/', $request->get('date'), $matches);
@@ -227,7 +227,7 @@ public function date(Request $request)
      * @param Request $request
      * @return string
      */
-    public function archive(Request $request)
+    public function archive(Request $request): string
     {
         // 記事一覧データ設定
         $options = array(
@@ -249,7 +249,7 @@ public function archive(Request $request)
      * @param Request $request
      * @return string
      */
-    public function preview(Request $request)
+    public function preview(Request $request): string
     {
         // XSS-Protection無効
         if (!headers_sent()) {
@@ -293,7 +293,7 @@ public function preview(Request $request)
      * @param Request $request
      * @return string
      */
-    private function preview_fc2_template(Request $request)
+    private function preview_fc2_template(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
 
@@ -332,7 +332,7 @@ private function preview_fc2_template(Request $request)
      * @param string $css テンプレートのCSS
      * @return string temporary compiled template file path
      */
-    public function test_template(Request $request, string $html, string $css)
+    public function test_template(Request $request, string $html, string $css): string
     {
         if (!defined("THIS_IS_TEST")) { // テスト以外ではブロックする
             throw new LogicException("the method is allowed only in testing.");
@@ -362,7 +362,7 @@ public function test_template(Request $request, string $html, string $css)
      * @param Request $request
      * @return string
      */
-    private function preview_template(Request $request)
+    private function preview_template(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
 
@@ -399,12 +399,11 @@ private function preview_template(Request $request)
      * @param Request $request
      * @return string
      */
-    private function preview_plugin(Request $request)
+    private function preview_plugin(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
 
         // プラグインのプレビュー情報取得
-        $preview_plugin = null;
         if ($request->get('plugin_id')) {
             // DBからプレビュー情報取得
             $preview_plugin = Model::load('Plugins')->findById($request->get('plugin_id'));
@@ -462,7 +461,7 @@ private function preview_plugin(Request $request)
         $this->setEntriesData($request, $options, $pages);
 
         // 通常のプラグインリストに追加する
-        $plugins = Model::load('BlogPlugins')->findByDeviceTypeAndCategory($this->getDeviceType(), $category, $blog_id);
+        $plugins = (new BlogPluginsModel())->findByDeviceTypeAndCategory($this->getDeviceType(), $category, $blog_id);
         $id = $request->get('id');
         if (empty($id)) {
             // 新規プラグインは最後尾に追加する
@@ -486,7 +485,7 @@ private function preview_plugin(Request $request)
      * @param Request $request
      * @return string
      */
-    private function preview_entry(Request $request)
+    private function preview_entry(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
 
@@ -589,7 +588,7 @@ public function view(Request $request): string
      * @param string $blog_id
      * @param array $entry
      */
-    private function setNextPrevEntryData(string $blog_id, array $entry)
+    private function setNextPrevEntryData(string $blog_id, array $entry): void
     {
         $entries_model = new EntriesModel();
         $blog_settings_model = new BlogSettingsModel();
@@ -670,7 +669,7 @@ private function isEntryNeedAuth($entry): bool
      * @param Request $request
      * @return string
      */
-    public function plugin(Request $request)
+    public function plugin(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
         $id = $request->get('id');
@@ -687,8 +686,9 @@ public function plugin(Request $request)
     /**
      * 記事のパスワード認証
      * @param Request $request
+     * @return string
      */
-    public function password(Request $request)
+    public function password(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
         $id = $request->get('id');
@@ -711,6 +711,7 @@ public function password(Request $request)
         }
 
         $this->redirect($request, array('action' => 'view', 'blog_id' => $blog_id, 'id' => $id));
+        return "";
     }
 
     /**
@@ -721,7 +722,7 @@ public function password(Request $request)
     public function blog_password(Request $request): string
     {
         $blog_id = $this->getBlogId($request);
-        $blog = $this->getBlog($blog_id);
+        $blog = BlogService::getById($blog_id);
 
         // プライベートブログではない、あるいは認証済み、ログイン済みならリダイレクト
         if ($blog['open_status'] != Config::get('BLOG.OPEN_STATUS.PRIVATE') || Session::get($this->getBlogPasswordKey($blog['id'])) || $this->isLoginBlog($request)) {
@@ -937,7 +938,7 @@ public function comment_edit(Request $request): string
      * @param Request $request
      * @return string
      */
-    public function comment_delete(Request $request)
+    public function comment_delete(Request $request): string
     {
         $comments_model = new CommentsModel();
 
@@ -973,7 +974,7 @@ public function comment_delete(Request $request)
      * @param array $areas
      * TODO: これはコントローラが持つべきなのか?Modelでは?
      */
-    private function setEntriesData(Request $request, $options = [], $areas = []): void
+    private function setEntriesData(Request $request, array $options = [], array $areas = []): void
     {
         $blog_id = $this->getBlogId($request);
         $page_num = $request->get('page', 0, Request::VALID_UNSIGNED_INT);
@@ -985,23 +986,12 @@ private function setEntriesData(Request $request, $options = [], $areas = []): v
         $this->set('entries', $this->getEntriesArray($blog_id, $options));
 
         // paging取得
-        $this->set('paging', $this->getPaging($options));
+        $this->set('paging', (new EntriesModel())->getPaging($options));
 
         // area引数がない場合 TOPページ判定
         $this->setAreaData($areas);
     }
 
-    /**
-     * @param array $options
-     * @return array
-     * TODO: これはコントローラが持つべきなのか?Modelでは?
-     */
-    public static function getPaging(array $options): array
-    {
-        $entries_model = new EntriesModel();
-        return $entries_model->getPaging($options);
-    }
-
     /**
      * @param string $blog_id
      * @param array $override_options
@@ -1058,7 +1048,7 @@ public static function getEntriesArray(string $blog_id, array $options): array
         // 記事のカテゴリ一覧を取得 TODO:後でcacheを使用する形に
         // 記事のカテゴリーとタグを一括で取得&振り分け
         $entry_ids = [];
-        foreach ($entries as $key => $entry) {
+        foreach ($entries as $entry) {
             $entry_ids[] = $entry['id'];
         }
         $categories_model = new CategoriesModel();
@@ -1077,7 +1067,7 @@ public static function getEntriesArray(string $blog_id, array $options): array
      * ページの表示可否設定を設定する
      * @param array $allows
      */
-    private function setAreaData($allows = [])
+    private function setAreaData(array $allows = []): void
     {
         $areas = [
             'index_area',     // トップページ
@@ -1105,7 +1095,7 @@ private function setAreaData($allows = [])
      * @param bool $is_preview
      * @return string
      */
-    private function getFc2TemplatePath($blog_id, string $html = null, string $css = null, bool $is_preview = false)
+    private function getFc2TemplatePath($blog_id, string $html = null, string $css = null, bool $is_preview = false): string
     {
         $device_type = $this->getDeviceType();
 
@@ -1138,7 +1128,7 @@ private function getFc2TemplatePath($blog_id, string $html = null, string $css =
      * @param $errors
      * @param array $data
      */
-    private function fc2CommentError($name, $errors, $data = array())
+    private function fc2CommentError($name, $errors, array $data = []): void
     {
         // FC2テンプレートとDB側の違い吸収
         $combine = array('password' => 'pass', 'open_status' => 'himitu');
@@ -1163,46 +1153,45 @@ private function fc2CommentError($name, $errors, $data = array())
         }
         $open_status_private = Config::get('COMMENT.OPEN_STATUS.PRIVATE');
         $comment_error = <<<HTML
-      <script>
-      function insertCommentErrorMessage(name, message){
-        let html = document.createElement('p');
-        html.style.cssText = "background-color: #fdd; color: #f00; border-radius: 3px; border: solid 2px #f44;padding: 3px; margin: 5px 3px;";
-        html.innerHTML = message;
-        let target = document.getElementsByName(name)[0];
-        if (!target) {
-          return ;
-        }
-        let parent = target.parentNode;
-        parent.insertBefore(html, target.nextSibling);
-      }
-      function setCommentData(name, value){
-        let target = document.getElementsByName(name)[0];
-        if (!target) {
-          return ;
-        }
-        if (target.type==='checkbox') {
-          if (value===$open_status_private) {
-            target.checked = 'checked';
+          <script>
+          function insertCommentErrorMessage(name, message){
+            let html = document.createElement('p');
+            html.style.cssText = "background-color: #fdd; color: #f00; border-radius: 3px; border: solid 2px #f44;padding: 3px; margin: 5px 3px;";
+            html.innerHTML = message;
+            let target = document.getElementsByName(name)[0];
+            if (!target) {
+              return ;
+            }
+            let parent = target.parentNode;
+            parent.insertBefore(html, target.nextSibling);
           }
-        } else {
-          target.value = value;
-        }
-      }
-      function displayCommentErrorMessage(){
-        {$js}
-      }
-      if( window.addEventListener ){
-          window.addEventListener( 'load', displayCommentErrorMessage, false );
-      }else { // noinspection JSUnresolvedVariable
-        if( window.attachEvent ){
-          window.attachEvent( 'onload', displayCommentErrorMessage );
-      }else{
-          window.onload = displayCommentErrorMessage;
-      } }
-      </script>
-    HTML;
+          function setCommentData(name, value){
+            let target = document.getElementsByName(name)[0];
+            if (!target) {
+              return ;
+            }
+            if (target.type==='checkbox') {
+              if (value===$open_status_private) {
+                target.checked = 'checked';
+              }
+            } else {
+              target.value = value;
+            }
+          }
+          function displayCommentErrorMessage(){
+            {$js}
+          }
+          if( window.addEventListener ){
+              window.addEventListener( 'load', displayCommentErrorMessage, false );
+          }else { // noinspection JSUnresolvedVariable
+            if( window.attachEvent ){
+              window.attachEvent( 'onload', displayCommentErrorMessage );
+          }else{
+              window.onload = displayCommentErrorMessage;
+          } }
+          </script>
+        HTML;
         $this->set('comment_error', $comment_error);
     }
-
 }
 
diff --git a/app/src/Web/Controller/User/UserController.php b/app/src/Web/Controller/User/UserController.php
index ed1e078e..489c88b8 100644
--- a/app/src/Web/Controller/User/UserController.php
+++ b/app/src/Web/Controller/User/UserController.php
@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace Fc2blog\Web\Controller\User;
 
@@ -9,7 +10,6 @@
 
 abstract class UserController extends Controller
 {
-
     /**
      * ブログID取得
      * @param Request $request
@@ -76,6 +76,7 @@ protected static function getBlogPasswordKey(string $blog_id): string
      */
     protected static function getEntryPasswordKey(string $blog_id, int $entry_id): string
     {
+        /** @noinspection PhpUnnecessaryStringCastInspection */
         return 'entry_password.' . $blog_id . '.' . (string)$entry_id;
     }
 }
diff --git a/app/src/Web/Cookie.php b/app/src/Web/Cookie.php
index 20422847..43a8fba0 100644
--- a/app/src/Web/Cookie.php
+++ b/app/src/Web/Cookie.php
@@ -1,7 +1,5 @@
 <?php
-/**
- * Cookieクラス
- */
+declare(strict_types=1);
 
 namespace Fc2blog\Web;
 
@@ -10,20 +8,16 @@
 
 class Cookie
 {
-
     /**
      * クッキーから情報を取得する
      * @param Request $request
      * @param string $key
-     * @param ?string $default
+     * @param mixed $default
      * @return mixed
      */
     public static function get(Request $request, string $key, $default = null)
     {
-        if (isset($request->cookie[$key])) {
-            return $request->cookie[$key];
-        }
-        return $default;
+        return $request->cookie[$key] ?? $default;
     }
 
     /**
@@ -60,27 +54,26 @@ public static function set(
         string $domain = "",
         bool $secure = false,
         bool $httponly = true,
-        string $samesite = "Lax")
+        string $samesite = "Lax"
+    )
     {
-        $params = [];
-        $params['expires'] = $expires;
-        $params['path'] = $path;
-        $params['domain'] = $domain;
+        $params = [
+            'expires' => $expires,
+            'path' => $path,
+            'domain' => $domain,
+        ];
 
         // SSLターミネーションがある環境においては検討が必要
-        if ($secure === true) {
-            if (!isset($request->server['HTTPS']) || $request->server['HTTPS'] !== "on") {
-                throw new InvalidArgumentException("secure=true needs https.");
-            }
-            $params['secure'] = true;
+        if ($secure === true && !$request->isHttps()) {
+            throw new InvalidArgumentException("secure=true needs https.");
         }
+        $params['secure'] = $secure;
 
         // setcookieではデフォルトfalseだが、セキュリティのためにtrueをデフォルト化
         if ($httponly === true) {
             $params['httponly'] = $httponly;
         }
 
-        // samesiteはhttp対応のために今後通常となるLaxをデフォルト
         if (false === in_array($samesite, static::cookieSamesiteAllowedList)) {
             throw new InvalidArgumentException("invalid samesite parameter");
         }
@@ -90,7 +83,7 @@ public static function set(
         if (strlen($domain) > 0) {
             $params['domain'] = $domain;
         } else if (strlen(Config::get('COOKIE_DEFAULT_DOMAIN')) > 0) {
-            $params['domain'] = $domain = Config::get('COOKIE_DEFAULT_DOMAIN');
+            $params['domain'] = Config::get('COOKIE_DEFAULT_DOMAIN');
         }
 
         // 不可能な組み合わせを拒否
@@ -104,10 +97,10 @@ public static function set(
             throw new InvalidArgumentException("samesite=None needs https.");
         }
 
-        if (defined("THIS_IS_TEST")) {
-            $request->cookie[$key] = $value;
-        } else {
-            $request->cookie[$key] = $value;
+        // 書き込み
+        $request->cookie[$key] = $value;
+        if (!defined("THIS_IS_TEST")) {
+            // unit testでなければcookieを書き込む
             setcookie(
                 $key,
                 $value,
diff --git a/app/src/Web/Html.php b/app/src/Web/Html.php
index 16ef8151..0506ecf6 100644
--- a/app/src/Web/Html.php
+++ b/app/src/Web/Html.php
@@ -1,4 +1,6 @@
 <?php
+declare(strict_types=1);
+
 namespace Fc2blog\Web;
 
 use Fc2blog\App;
@@ -43,7 +45,7 @@ public static function adminUrl(Request $request, string $controller, string $ac
      * @param bool $use_base_dir
      * @return string
      */
-    public static function url(Request $request, $args = array(), $reused = false, $full_url = false, $use_base_dir = true)
+    public static function url(Request $request, array $args = array(), bool $reused = false, bool $full_url = false, bool $use_base_dir = true): string
     {
         // 現在のURLの引数を引き継ぐ
         if ($reused == true) {
@@ -100,7 +102,7 @@ public static function url(Request $request, $args = array(), $reused = false, $
         $params[] = Config::get('ARGS_CONTROLLER') . '=' . $controller;
         $params[] = Config::get('ARGS_ACTION') . '=' . $action;
         foreach ($args as $key => $value) {
-            $params[] = $key . '=' . rawurlencode($value);
+            $params[] = $key . '=' . rawurlencode((string)$value);
         }
         if (!empty($device_name)) {
             $params[] = $device_name;
@@ -118,7 +120,7 @@ public static function url(Request $request, $args = array(), $reused = false, $
         if (
             $blog_id && (
                 // Default Blog IDが未指定か
-                strlen(Config::get('DEFAULT_BLOG_ID')) === 0 ||
+                strlen(Config::get('DEFAULT_BLOG_ID', "")) === 0 ||
                 // 指定されたblog_idがDefault blog idと異なる場合
                 $blog_id !== Config::get('DEFAULT_BLOG_ID')
             )
@@ -133,11 +135,12 @@ public static function url(Request $request, $args = array(), $reused = false, $
         return $url;
     }
 
-    public static function input(Request $request, $name, $type, $attrs = array(), $option_attrs = array())
+    /** @noinspection XmlInvalidId HTML組み立てが複雑で、Linterが解析しきれないため */
+    public static function input(Request $request, $name, $type, $attrs = array(), $option_attrs = array()): string
     {
-        $default = isset($attrs['default']) ? $attrs['default'] : null;    // デフォルト文字列
-        $options = isset($attrs['options']) ? $attrs['options'] : array(); // オプション
-        $label = isset($attrs['label']) ? $attrs['label'] : '';          // ラベル
+        $default = $attrs['default'] ?? null;    // デフォルト文字列
+        $options = $attrs['options'] ?? array(); // オプション
+        $label = $attrs['label'] ?? '';          // ラベル
         unset($attrs['default'], $attrs['options'], $attrs['label']);
 
         // Requestの親キー(default判定)
@@ -175,11 +178,11 @@ public static function input(Request $request, $name, $type, $attrs = array(), $
                 break;
 
             case 'text':
-                $html = '<input type="text" ' . $attr . ' value="' . h($rvalue) . '" />';
+                $html = '<input type="text" ' . $attr . ' value="' . h((string)$rvalue) . '" />';
                 break;
 
             case 'password':
-                $html = '<input type="password" ' . $attr . ' value="' . h($rvalue) . '" />';
+                $html = '<input type="password" ' . $attr . ' value="' . h((string)$rvalue) . '" />';
                 break;
 
             case 'blank_password':
@@ -192,7 +195,7 @@ public static function input(Request $request, $name, $type, $attrs = array(), $
                 break;
 
             case 'hidden':
-                $html = '<input type="hidden" ' . $attr . ' value="' . h($rvalue) . '" />';
+                $html = '<input type="hidden" ' . $attr . ' value="' . h((string)$rvalue) . '" />';
                 break;
 
             case 'token':
@@ -204,7 +207,7 @@ public static function input(Request $request, $name, $type, $attrs = array(), $
                 break;
 
             case 'textarea':
-                $html = '<textarea ' . $attr . '>' . h($rvalue) . '</textarea>';
+                $html = '<textarea ' . $attr . '>' . h((string)$rvalue) . '</textarea>';
                 break;
 
             case 'select':
@@ -215,7 +218,7 @@ public static function input(Request $request, $name, $type, $attrs = array(), $
                         if (!isset($option['value'])) {
                             $html .= '<optgroup label="' . $key . '">';
                             foreach ($option as $k => $v) {
-                                $html .= '<option value="' . $k . '" ' . ($rvalue !== null && $k == $rvalue ? 'selected="selected"' : '') . '>' . h($v) . '</option>';
+                                $html .= '<option value="' . $k . '" ' . ($rvalue !== null && $k == $rvalue ? 'selected="selected"' : '') . '>' . h((string)$v) . '</option>';
                             }
                             $html .= '</optgroup>';
                             continue;
@@ -225,10 +228,10 @@ public static function input(Request $request, $name, $type, $attrs = array(), $
                         if (!empty($option['disabled'])) {
                             $optionAttr .= ' disabled="disabled" ';
                         }
-                        $html .= '<option value="' . $key . '" ' . $optionAttr . '>' . str_repeat('&nbsp;&nbsp;&nbsp;', $option['level'] - 1) . h($option['value']) . '</option>';
+                        $html .= '<option value="' . $key . '" ' . $optionAttr . '>' . str_repeat('&nbsp;&nbsp;&nbsp;', $option['level'] - 1) . h((string)$option['value']) . '</option>';
                     } else {
                         // 通常のオプション
-                        $html .= '<option value="' . $key . '" ' . ($rvalue !== null && $key == $rvalue ? 'selected="selected"' : '') . '>' . h($option) . '</option>';
+                        $html .= '<option value="' . $key . '" ' . ($rvalue !== null && $key == $rvalue ? 'selected="selected"' : '') . '>' . h((string)$option) . '</option>';
                     }
                 }
                 $html .= '</select>';
@@ -272,6 +275,7 @@ public static function input(Request $request, $name, $type, $attrs = array(), $
 
     public static function getServerUrl(Request $request): string
     {
+        /** @noinspection HttpUrlsUsage */
         $url = $request->isHttps() ? 'https://' : 'http://';
         $url .= Config::get('DOMAIN');
         $url .= $request->isHttps() ? Config::get('HTTPS_PORT_STR') : Config::get('HTTP_PORT_STR');
diff --git a/app/src/Web/Request.php b/app/src/Web/Request.php
index 923bb13c..c50ee3ee 100644
--- a/app/src/Web/Request.php
+++ b/app/src/Web/Request.php
@@ -1,15 +1,11 @@
 <?php
-/**
- * リクエストクラス
- * POST,GETへのアクセスを便利にするクラス
- */
+declare(strict_types=1);
 
 namespace Fc2blog\Web;
 
 use Fc2blog\App;
 use Fc2blog\Util\I18n;
 use Fc2blog\Util\Log;
-use Fc2blog\Web\Controller\User\CommonController;
 use Fc2blog\Web\Router\Router;
 
 class Request
@@ -33,11 +29,11 @@ class Request
     public $env = [];
     public $cookie = [];
 
-    public $className = CommonController::class;
-    public $methodName = "index";
-    public $shortControllerName = "Common";
-    public $lang = "";
-    public $deviceType = "";
+    public $className;
+    public $methodName;
+    public $shortControllerName;
+    public $lang;
+    public $deviceType;
     public $urlRewrite = true;
     public $baseDirectory = "/";
 
@@ -104,10 +100,7 @@ public function __construct(
      */
     public function getReferer(): string
     {
-        if (isset($this->server['HTTP_REFERER'])) {
-            return $this->server['HTTP_REFERER'];
-        }
-        return '';
+        return $this->server['HTTP_REFERER'] ?? '';
     }
 
     public function getPath()
@@ -125,7 +118,7 @@ public function getQuery()
         return $this->query;
     }
 
-    public function getGet()
+    public function getGet(): array
     {
         return $this->get;
     }
@@ -207,24 +200,22 @@ public function get($key, $default = null, $valid = self::VALID_NOT_EMPTY, $opti
         return $data;
     }
 
-
     /**
      * intデータかチェック
      * @param $int
      * @return bool
      */
-    private function is_integer($int)
+    private function is_integer($int): bool
     {
         return ((string)intval($int) === (string)$int);
     }
 
-
     /**
      * 引数が存在するかチェック
      * @param $key
      * @return bool
      */
-    public function isArgs($key)
+    public function isArgs($key): bool
     {
         // .区切りのキーを解釈
         $data = $this->request;
@@ -294,7 +285,7 @@ private function _delete($keys, &$request, $count, $i = 0)
      * キーの入れ替えを行う
      * @param array $comb
      */
-    public function combine($comb = array())
+    public function combine(array $comb = []): void
     {
         foreach ($comb as $key => $value) {
             $this->set($value, $this->get($key));
@@ -311,16 +302,6 @@ public function isGet(): bool
         return $this->method === 'GET';
     }
 
-    /**
-     * @param string $key
-     * @param string|array|null $default
-     * @return string|array|null
-     */
-    public function rawGet(string $key, $default = null)
-    {
-        return isset($this->get[$key]) ? $this->get[$key] : $default;
-    }
-
     /**
      * @param string $key
      * @return bool
@@ -330,25 +311,6 @@ public function rawHasGet(string $key): bool
         return isset($this->get[$key]);
     }
 
-    /**
-     * @param string $key
-     * @param string|array|null $default
-     * @return string|array|null
-     */
-    public function rawPost(string $key, $default = null)
-    {
-        return isset($this->post[$key]) ? $this->post[$key] : $default;
-    }
-
-    /**
-     * @param string $key
-     * @return bool
-     */
-    public function rawHasPost(string $key): bool
-    {
-        return isset($this->post[$key]);
-    }
-
     /**
      * @param string $key
      * @param string|array|null $default
@@ -356,16 +318,7 @@ public function rawHasPost(string $key): bool
      */
     public function rawCookie(string $key, $default = null)
     {
-        return isset($this->cookie[$key]) ? $this->cookie[$key] : $default;
-    }
-
-    /**
-     * @param string $key
-     * @return bool
-     */
-    public function rawHasCookie(string $key): bool
-    {
-        return isset($this->cookie[$key]);
+        return $this->cookie[$key] ?? $default;
     }
 
     /**
@@ -405,8 +358,8 @@ public function isValidSig(): bool
             return false;
         }
         if (
-            !is_string($this->get('sig', null)) ||
-            strlen($this->get('sig', "") === 0)
+            !is_string($this->get('sig')) ||
+            strlen($this->get('sig', "")) === 0
         ) {
             error_log("request did not have sig.");
             return false;
@@ -423,7 +376,7 @@ public function generateNewSig(): void
     }
 
     /**
-     * BlogID「かもしれない」ものを取得する
+     * BlogID「かもしれない」ものをURLから取得する
      * @return string|null
      */
     public function getBlogId(): ?string
diff --git a/app/src/Web/Session.php b/app/src/Web/Session.php
index 8f33a012..b877e98e 100644
--- a/app/src/Web/Session.php
+++ b/app/src/Web/Session.php
@@ -1,7 +1,5 @@
 <?php
-/**
- * Sessionクラス
- */
+declare(strict_types=1);
 
 namespace Fc2blog\Web;
 
@@ -9,19 +7,9 @@
 
 class Session
 {
-
-    private static $isStart = false;
-
-    private function __construct()
-    {
-    }
-
-    public static function start()
+    public static function start(): void
     {
-        if (self::$isStart) {
-            return;
-        }
-        if (headers_sent()) {
+        if (session_status() === PHP_SESSION_ACTIVE || headers_sent()) {
             return;
         }
 
@@ -40,46 +28,40 @@ public static function start()
         session_set_cookie_params($session_cookie_options);
         session_name(Config::get('SESSION_NAME'));
         session_start();
-        self::$isStart = true;
     }
 
     /**
      * セッションから情報を取得する
-     * @param $key
+     * @param string $key
      * @param null $default
      * @return mixed|null
      */
-    public static function get($key, $default = null)
+    public static function get(string $key, $default = null)
     {
         self::start();
-        if (isset($_SESSION[$key])) {
-            return $_SESSION[$key];
-        }
-        return $default;
+        return $_SESSION[$key] ?? $default;
     }
 
     /**
      * セッションから情報を取得し破棄する
-     * @param $key
-     * @param null $default
+     * @param string $key
+     * @param mixed|null $default
      * @return mixed|null
      */
-    public static function remove($key, $default = null)
+    public static function remove(string $key, $default = null)
     {
         self::start();
-        if (isset($_SESSION[$key])) {
-            $default = $_SESSION[$key];
-            unset($_SESSION[$key]);
-        }
-        return $default;
+        $tmp = $_SESSION[$key] ?? $default;
+        unset($_SESSION[$key]);
+        return $tmp;
     }
 
     /**
      * セッションに情報を保存する
-     * @param $key
-     * @param $value
+     * @param string $key
+     * @param mixed $value
      */
-    public static function set($key, $value)
+    public static function set(string $key, $value): void
     {
         self::start();
         $_SESSION[$key] = $value;
@@ -88,7 +70,7 @@ public static function set($key, $value)
     /**
      * セッションID置き換え
      */
-    public static function regenerate()
+    public static function regenerate(): void
     {
         self::start();
         if (session_status() === PHP_SESSION_ACTIVE) {
@@ -100,7 +82,7 @@ public static function regenerate()
      * セッションを破棄
      * @param Request $request
      */
-    public static function destroy(Request $request)
+    public static function destroy(Request $request): void
     {
         $_SESSION = [];
         $request->session = [];
@@ -111,6 +93,5 @@ public static function destroy(Request $request)
             session_destroy();
         }
     }
-
 }
 
diff --git a/app/src/config/fc2_default_plugin.php b/app/src/config/fc2_default_plugin.php
index 8b7eed6a..71fc1ea4 100644
--- a/app/src/config/fc2_default_plugin.php
+++ b/app/src/config/fc2_default_plugin.php
@@ -1,4 +1,4 @@
-<?php
+<?php /** @noinspection ALL */
 
 $config = array();
 
diff --git a/app/src/config/fc2_template.php b/app/src/config/fc2_template.php
index 90604c6c..965ac1c6 100644
--- a/app/src/config/fc2_template.php
+++ b/app/src/config/fc2_template.php
@@ -1,4 +1,4 @@
-<?php
+<?php /** @noinspection ALL */
 
 $config = [];
 
diff --git a/app/src/include/bootstrap.php b/app/src/include/bootstrap.php
index 833d1756..b0929a64 100644
--- a/app/src/include/bootstrap.php
+++ b/app/src/include/bootstrap.php
@@ -1,4 +1,4 @@
-<?php
+<?php /** @noinspection PhpFullyQualifiedNameUsageInspection */
 
 define('REQUEST_MICROTIME', microtime(true)); // 開始タイムスタンプ(ミリ秒含む)
 define('APP_DIR', realpath(__DIR__ . '/../../') . '/'); // APPディレクトリのパス
diff --git a/app/src/include/common_functions.php b/app/src/include/common_functions.php
index ecd6dae8..7c90877c 100644
--- a/app/src/include/common_functions.php
+++ b/app/src/include/common_functions.php
@@ -1,4 +1,4 @@
-<?php
+<?php /** @noinspection PhpFullyQualifiedNameUsageInspection */
 // the file will be load by composer autoloader.
 
 /**