Closed testAccountDeltas closed 4 months ago
The bug is really a call to the GoogleTranslate library. I have now rewritten the GoogleTranslate functionality and I don’t have a single error.
Hey @testAccountDeltas,
glad that you could solve it. I am sorry to tell you, that I have not been able to reproduce the error so far. As your problem seems gone, I'll close this ticket.
Well, if we assume that the solution to the problem is solved by rewriting the library functionality, you are right.
This error appears on php 8.3.8 with the latest sources parallel
The code provided is for informational purposes only and is not a test code. The problem is mainly connecting the GoogleTranslate library
Example code
```php use Stichoza\GoogleTranslate\GoogleTranslate; function GoogleTranslateData($langSoruce, $langTarget, $data) { try { $tr = new GoogleTranslate(); if($langSoruce && is_string($langSoruce) && trim($langSoruce)) { $tr->setSource($langSoruce); } if($langTarget && is_string($langTarget) && trim($langTarget)) { $tr->setTarget($langTarget); return trim($tr->translate($data)); } else { return false; } } catch (Exception $e) { echo 'Caught exception (GoogleTranslateDataTR): ', $e->getMessage(), "\n"; } return false; } ``` class func GoogleTranslateData ```php public function getTranslationCategories($threadsParseCount, $streamsCount, callable $callback) { $langTranslationTest = []; $categoriesList = $this->getTranslationCategoriesList($threadsParseCount); foreach($categoriesList['translation'] as $langTarget => $langSoruce) { (new ThreadArray($streamsCount))->start($categoriesList['categories'], function($max, $current, $categoryValue, $callback, $langSoruce, $langTarget) { $nameCategoryFile = md5($categoryValue); if(!$this->distCategoryISFile($langTarget, $nameCategoryFile)) { $dataTranslate = GoogleTranslateData($langSoruce, $langTarget, $categoryValue); if($dataTranslate !== false) { $dataWrite = [ 'valueOrig' => $categoryValue, 'value' => $dataTranslate ]; $this->distCategoryFileWrite($langTarget, $nameCategoryFile, $dataWrite); if(is_callable($callback)) { $callback($max, $current, ['name' => $categoryValue], ['name' => $dataTranslate]); } } } return false; }, $callback, $langSoruce, $langTarget); } } ```all other code
ThreadArray ```php trait filesDistTranslationFunction { // Получим полный путь до папки категорий public function distCategoriesLangFilesDir($lang) { return $this->filesDir('distCategoriesLangFiles_' . $lang); } // Получим полный путь до файла категории public function distCategoryFilePath($lang, $item) { return $this->fileDir('distCategoriesLangFiles_' . $lang, $item); } // Проверим существует ли файл категории public function distCategoryISFile($lang, $item) { return $this->fileDirIs('distCategoriesLangFiles_' . $lang, $item); } // Читаем файл категории public function distCategoryFile($lang, $filePath) { return $this->fileRead('distCategoriesLangFiles_' . $lang, $filePath); } // Для записи в файл категории public function distCategoryFileWrite($lang, $item, $data, $lastmod = false) { return $this->fileWrite('distCategoriesLangFiles_' . $lang, $item, $data, $lastmod); } // Получим файлы из папки категории public function distCategoriesFiles($lang) { return iterator_to_array(GetFilesGenerator('/.json/', true, $this->distCategoriesLangFilesDir($lang))); } private function getTranslationCategoriesList($streamsCount) { if(is_array($categories = (new ThreadArray($streamsCount))->start($this->distFiles(), function($max, $current, $filePath) { $dataFile = $this->distFile($filePath); $categories = []; if(isset($dataFile['categories']) && is_array($dataFile['categories'])) { $categories = $dataFile['categories']; if(isset($dataFile['categories']) && (bool)$dataFile['categoriesNewFirstNameSkipTranslation']) { if(count($categories)) { $categories = array_splice($categories, 1); } } } $langList = isset($dataFile['langTranslation']) ? $dataFile['langTranslation'] : []; if(is_string($langList)) { $langList = (array)$langList; } if(!is_array($langList)) { $langList = []; } $langList = array_flip($langList); foreach($langList as $indexLang => $indexValue) { $langList[$indexLang] = isset($dataFile['langPage']) ? $dataFile['langPage'] : false; } return [ 'translation' => $langList, 'categories' => $categories, ]; }))) { $resultCategories = [ 'translation' => [], 'categories' => [] ]; foreach($categories as $itemDataArray) { foreach($itemDataArray as $itemData) { if(!count($itemData['categories'])) { continue; } $resultCategories['translation'] = array_merge($resultCategories['translation'], $itemData['translation']); $resultCategories['categories'] = array_merge($resultCategories['categories'], $itemData['categories']); } } $resultCategories['categories'] = array_unique($resultCategories['categories']); } else { $resultCategories = []; } return $resultCategories; } public function getTranslationCategories($threadsParseCount, $streamsCount, callable $callback) { $langTranslationTest = []; $categoriesList = $this->getTranslationCategoriesList($threadsParseCount); foreach($categoriesList['translation'] as $langTarget => $langSoruce) { (new ThreadArray($streamsCount))->start($categoriesList['categories'], function($max, $current, $categoryValue, $callback, $langSoruce, $langTarget) { $nameCategoryFile = md5($categoryValue); if(!$this->distCategoryISFile($langTarget, $nameCategoryFile)) { $dataTranslate = GoogleTranslateData($langSoruce, $langTarget, $categoryValue); if($dataTranslate !== false) { $dataWrite = [ 'valueOrig' => $categoryValue, 'value' => $dataTranslate ]; $this->distCategoryFileWrite($langTarget, $nameCategoryFile, $dataWrite); if(is_callable($callback)) { $callback($max, $current, ['name' => $categoryValue], ['name' => $dataTranslate]); } } } return false; }, $callback, $langSoruce, $langTarget); } } public function distTranslation($threadsParseCount, $streamsCount, callable $callback) { $categoriesLang = $this->getTranslationCategories($threadsParseCount, $streamsCount, $callback); // ... other code } // ... other code } ``` ```php use parallel\Runtime; use parallel\Future; use parallel\Error\Error; class ThreadError { public $message = ''; public $trace = ''; public function __construct($message, $trace) { $this->message = $message; $this->trace = $trace; } public function getError() { return "Error: {$this->message}\nTrace: {$this->trace}"; } } class Thread { private $runtimes = []; private $errorHandler; public static function errorHandle($error) { echo $error->getError(); } public function __construct(callable $errorHandler = null) { $this->errorHandler = is_null($errorHandler) ? 'Thread::errorHandle' : $errorHandler; } public function runReturn(callable $task, callable $taskResult, ...$args) { $item = (new Runtime(__DIR__ . '/include.php'))->run(function ($task, $errorHandler, $taskResult, ...$args) { ini_set('memory_limit', '-1'); set_time_limit(0); set_error_handler(function ($errno, $errstr, $errfile, $errline) { throw new ErrorException($errstr, $errno, 0, $errfile, $errline); }); try { $value = $task(...$args); if (is_callable($taskResult)) { $taskResult($value); } return $value; } catch (Throwable $e) { ($errorHandler)(new ThreadError($e->getMessage(), $e->getTraceAsString())); } finally { restore_error_handler(); } }, [$task, $this->errorHandler, $taskResult, ...$args]); $this->runtimes[] = $item; return $item; } public function run(callable $task, ...$args) { return $this->runReturn($task, function () {}, ...$args); } public function wait() { $resultAll = []; foreach ($this->runtimes as $index => $future) { while (!$future->done()) { usleep(10000); } $result = $future->value(); if (!($result instanceof ThreadError)) { $resultAll[] = $result; } unset($this->runtimes[$index]); } $this->runtimes = array_values($this->runtimes); return $resultAll; } public function killRuntimes() { foreach ($this->runtimes as &$future) { if($future instanceof parallel\Future) { $future->kill(); } } $this->runtimes = []; } public function __destruct() { $this->runtimes = []; } } class ThreadArray extends Thread { private $streamsCount; private $usleep; public function __construct(int $streamsCount = 5, int $usleep = 0, callable $errorHandler = null) { parent::__construct($errorHandler); $this->streamsCount = $streamsCount; $this->usleep = $usleep; } public function set_streams_count(int $streamsCount) { $this->streamsCount = $streamsCount; } public function get_streams_count() { return $this->streamsCount; } public function start($ArrayLines, callable $callback, ...$args) { $ArrayLines = (array) $ArrayLines; $maxIndex = count($ArrayLines); if (!$maxIndex) return []; $currentIndex = new parallel\Sync(0); foreach (array_chunk($ArrayLines, ceil($maxIndex / $this->streamsCount)) as $index => $chunk) { $this->run(function ($chunk, $maxIndex, $callback, $usleep, ...$args) use ($currentIndex) { $results = []; $start = true; foreach ($chunk as $ItemArray) { if(!$start && $usleep) usleep($usleep); $currentIndex->set((int)$currentIndex->get() + 1); if($value = $callback($maxIndex, (int)$currentIndex->get(), $ItemArray, ...$args)) { $results[] = $value; } $start = false; } return $results; }, $chunk, $maxIndex, $callback, $this->usleep, ...$args); } return $this->wait(); } } ```