Selaa lähdekoodia

fix: 修复json_encode() 遇到非 UTF-8 字节会返回 false的问题

runphp 1 viikko sitten
vanhempi
sitoutus
b8dce68077
1 muutettua tiedostoa jossa 30 lisäystä ja 11 poistoa
  1. 30 11
      src/Service/NewsFfiService.php

+ 30 - 11
src/Service/NewsFfiService.php

@@ -81,6 +81,20 @@ class NewsFfiService
         return self::$instance;
     }
 
+    /**
+     * Safely encode data to JSON, replacing invalid UTF-8 bytes instead of failing.
+     * PHP 7.2+ provides JSON_INVALID_UTF8_SUBSTITUTE to handle malformed bytes gracefully.
+     * Falls back to '{}' on non-UTF8-related encoding failures (e.g. recursion).
+     */
+    private function safeJsonEncode(mixed $data): string
+    {
+        try {
+            return json_encode($data, JSON_INVALID_UTF8_SUBSTITUTE | JSON_THROW_ON_ERROR);
+        } catch (\JsonException) {
+            return '{}';
+        }
+    }
+
     /**
      * Generic private method to handle FFI calls, reducing code duplication.
      * It marshals arguments to C-compatible types and unmarshals the JSON result.
@@ -110,29 +124,31 @@ class NewsFfiService
     public function getCategoryList(array $where = []): array
     {
         $payload = empty($where) ? new \stdClass() : $where;
-        return $this->call('GetCategoryList', json_encode($payload));
+        return $this->call('GetCategoryList', $this->safeJsonEncode($payload));
     }
 
     public function getCategoryById(int $id): array
     {
-        return $this->call('GetCategoryByID', $id);
+        $result = $this->call('GetCategoryByID', $id);
+        return is_array($result) ? $result : [];
     }
 
     public function createCategory(array $data): array
     {
         $payload = empty($data) ? new \stdClass() : $data;
-        return $this->call('CreateCategory', json_encode($payload));
+        return $this->call('CreateCategory', $this->safeJsonEncode($payload));
     }
 
     public function updateCategory(int $id, array $data): array
     {
         $payload = empty($data) ? new \stdClass() : $data;
-        return $this->call('UpdateCategory', $id, json_encode($payload));
+        return $this->call('UpdateCategory', $id, $this->safeJsonEncode($payload));
     }
 
     public function deleteCategory(int $id): array
     {
-        return $this->call('DeleteCategory', $id);
+        $result = $this->call('DeleteCategory', $id);
+        return is_array($result) ? $result : [];
     }
 
     // --- News Service Wrappers ---
@@ -140,34 +156,37 @@ class NewsFfiService
     public function getNewsList(array $params = []): array
     {
         $payload = empty($params) ? new \stdClass() : $params;
-        return $this->call('GetNewsList', json_encode($payload));
+        return $this->call('GetNewsList', $this->safeJsonEncode($payload));
     }
 
     public function getNewsById(int $id): array
     {
-        return $this->call('GetNewsByID', $id);
+        $result = $this->call('GetNewsByID', $id);
+        return is_array($result) ? $result : [];
     }
 
     public function createNews(array $data): array
     {
         $payload = empty($data) ? new \stdClass() : $data;
-        $result = $this->call('CreateNews', json_encode($payload));
+        $result = $this->call('CreateNews', $this->safeJsonEncode($payload));
         return is_array($result) ? $result : [];
     }
 
     public function updateNews(int $id, array $data): array
     {
         $payload = empty($data) ? new \stdClass() : $data;
-        return $this->call('UpdateNews', $id, json_encode($payload));
+        return $this->call('UpdateNews', $id, $this->safeJsonEncode($payload));
     }
 
     public function deleteNews(int $id): array
     {
-        return $this->call('DeleteNews', $id);
+        $result = $this->call('DeleteNews', $id);
+        return is_array($result) ? $result : [];
     }
 
     public function incrementNewsViews(int $id): array
     {
-        return $this->call('IncrementNewsViews', $id);
+        $result = $this->call('IncrementNewsViews', $id);
+        return is_array($result) ? $result : [];
     }
 }