我没有编程经验。我试图在laravel中创建一个备份表的控制器。这些表已正确备份,但是我收到一些评论说我的代码很容易被破坏。我一直在尽力而为,但是我真的很精疲力尽,感到沮丧。 我有一个表,表中的每一行占用1到10 MB的内存。表100中的总行。最大内存量(memory_limit)设置为35 MB。什么是解决此问题的最佳方法?我真的很感谢任何建议或帮助。这是我的代码:
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;
}
}
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();
}
}
答案 0 :(得分:0)
您不需要使用PHP处理该数据。您可以在laravel中简单地使用原始SQL查询:
SELECT *
INTO tableToBeBackedUp
FROM currentTable;