php - 在 Laravel 中创建备份 Controller

标签 php mysql laravel

我没有编程经验。我正在尝试在 laravel 中创建一个备份表的 Controller 。这些表已正确备份,但我收到一些评论说我的代码很容易被破坏。我一直在努力做到最好,但我真的很累,而且很沮丧。 我有一个表,表中的每一行占用 1 到 10 MB 的内存。表 100 中的总行数。最大内存量 (memory_limit) 设置为 35 MB。 解决此问题的最佳方法是什么?我真的很感谢任何建议或帮助。这是我的代码:

  1. BackupController 类

    <?php
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Storage;
    use Illuminate\Database\Events\StatementPrepared; // set the fetch mode
    use Illuminate\Support\Facades\Cache;
    use Carbon\Carbon;
    use Illuminate\Support\Facades\Schema;
    use DB;
    use App\Post;
    use App\User;
    use App\Jobs\BackupTableJob;
    use Artisan;
    
    class BackupController extends Controller
    {
        const MAX_VALUE = 35000; //kilobytes 
    
        public function lockTable()
        {
            // lock all tables
            DB::unprepared('FLUSH TABLES WITH READ LOCK;');
        }
    
        public function setQueueJob(User $user, Post $post)
        {
            BackupTableJob::dispatch($user, $post)
                ->delay(Carbon::now()
                ->addSeconds(5));
            // Artisan::call('queue:work');     
        }
    
        public function unlockTable()
        {
            // unlock all tables
            DB::unprepared('UNLOCK TABLES');
        }
    
        public function queryFetch($data)
        {
            $pdo  = DB::connection()->getPdo();
            $stmt = $pdo->prepare($data);
            $stmt->execute();
            // $stmt = $pdo->query($data);
            $results = $stmt->fetch();
            return $results;
        }
    
        public function create(Request $request)
        {
            $this->setPdoMode();
            $numTables = DB::select("SHOW TABLES");
            $countUserRecords = User::count();
            $countPostRecords = Post::count();
    
            return view('backup', compact('numTables','countUserRecords', 'countPostRecords'));
        }
    
        public function setPdoMode()
        {
            \Event::listen(StatementPrepared::class, function($event) {
            $event->statement->setFetchMode(\PDO::FETCH_ASSOC);});
        }
    
        // public function backup(Request $request, User $user, Post $post)
        public function backup(Request $request, User $user, Post $post)
        {
           $this->setQueueJob($user, $post);          
           if ($request->all()) {
               $tables = request('table');
               $output = '';     
               foreach ($tables as $key => $table) {  
                   $this->lockTable();
                   $show_table_query = $this->queryFetch("SHOW CREATE TABLE {$table}");
                   $output .="\n" . $show_table_query[1] . ";\n";
                   $this->setPdoMode();
                   $single_result = DB::select("SELECT * FROM {$table}");
                   $output .= $this->getTableData($single_result, $table);
                   $output .= $this->cacheData($table, $output); 
               }
               if ($this->checkFileSize($output)) {
                   return redirect()->route('create'); 
               }                  
            }             
            return redirect()->route('backupError'); 
        }
    
        // Stores the file in this location: storage/app
        public function download($output)
        {
            $dt = Carbon::now();
            $file_name = 'backup_on[' . $dt->format('y-m-d H-i-s') . '].sql';
            Storage::disk('local')->put($file_name, $output);
        }
    
        public function getTableData($single_result, $table) 
        {
            $this->unlockTable();
            $output = '';
            foreach ($single_result as $key => $table_val) {
                if ($table === "posts" || $table === "users") {
                    $output .= "\nINSERT INTO $table("; 
                    $output .= "" .addslashes(implode(", ", array_keys($table_val))) . ") VALUES(";
                    $output .= "'" . addslashes(implode("','", array_values($table_val))) . "');\n";
                }  
            }
            // $output .= $this->cacheData($table, $output);   
            return $output;
        }
    
        public function checkFileSize($file)
        {
            $file_size = strlen($file);
            // convert bytes to kilobytes 
            $file_size = round($file_size / 1024, 0, PHP_ROUND_HALF_UP);
            if ($file_size <= self::MAX_VALUE) {
                $this->download($file);
                return true;
            } 
            return false;               
        }
    
        public function cacheData($table, $data)
        {
            // $table = $table;
            $start = microtime(true);
            $data = Cache::remember('table', 10, function() use ($table){
                return DB::table($table)->get();
            });
            $duration = (microtime(true) -$start) * 1000;
    
            \Log::info("From cache: " . $duration .' ms');
            return $data;
        }
     }
    
  2. BackupTableJob 类

    <?php
    
    namespace App\Jobs;
    
    use App\User;
    use App\Post;
    use App\Http\Controllers\BackupController;
    use Illuminate\Http\Request;
    
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    
    class BackupTableJob implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable; //SerializesModels;
    
        protected $user;
        protected $post;
    
        /**
         * Create a new job instance.
         *
         * @return void
         */
        public function __construct(User $user, Post $post)
        // public function __construct()
        {
            $this->user = $user;
            $this->post = $post;
        }
    
        /**
         * Execute the job.
         *
         * @return void
         */
        public function handle()
        {
            // $this->user->save();
            // $this->post->save();
        }
    }
    

最佳答案

您不需要使用 PHP 处理该数据。您可以简单地在 Laravel 中使用原始 SQL 查询:

SELECT *
INTO tableToBeBackedUp
FROM currentTable;

关于php - 在 Laravel 中创建备份 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51310800/

相关文章:

php - Mysql-php mysql_fetch_array()

mysql - 在 MySQL 中旋转数据。

php - Laravel eloquent 如果 'anonym' 字段为 1,则将 'username' 更改为匿名

php - 使用不同语言从数据库中选择类别

php - 在 AngularJS 中捕获 PDO 异常

routing - Laravel 4 托管在在线共享服务器上

php - laravel 具有多对多关系的本地范围

php - 当我在php中点击产品时如何添加描述?

php - websocket.ERROR:发生连接错误警告:SessionHandler::read(): session 未激活

php - 如何使用 PHP 中的 html 删除按钮从 MySQL 表数据中删除一行