だから私はLaravelに完全な初心者です。ここで何かを試してみます。CSVファイルを2つのテーブルにインポートしたいのですが、リストとテーブル名とclient_id
。
その後、client_id
とlist_id
だけでなく、名前の姓の連絡先番号を取得するcustomersというテーブルがあります。
私が達成したいのは、ファイル名を取得してリストテーブルに保存するCSVファイルをインポートしてから、CSVファイルを介して配列を作成し、リストとクライアントIDで顧客テーブルにデータをインポートすることです。
最初の部分を完了し、リストテーブルに正しく挿入します。ストレージ/ドキュメントにあるCSVから配列を作成し、それを顧客テーブルに挿入する方法を教えてください。
namespace App\Http\Controllers;
use Input;
use DB;
use Illuminate\Http\Request;
use App\Http\Requests\ListsRequest;
use App\Lists;
use App\Clients;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class ListsController extends Controller {
public function index()
{
// $list_items = Lists::all();
$clients = Clients::all();
return view('lists.show', compact('clients'));
}
public function store(Requests\ListsRequest $request)
{
$input = $request->input();
Lists::create($input);
if (Input::hasFile('name'))
{
$file = Input::file('name');
$name = time() . '-' . $file->getClientOriginalName();
$path = storage_path('documents');
$file->move($path, $name);
// All works up to here
// All I need now is to create an array
// from the CSV and insert into the customers database
}
}
}
私は受け入れた回答を使用することを選択しましたが、他の回答でも遊んで、このように動作するようにしました。
public function store(Requests\ListsRequest $request)
{
$input = $request->input();
$client_id = $request->input('client_id');
if (Input::hasFile('name'))
{
$file = Input::file('name');
$name = time() . '-' . $file->getClientOriginalName();
$path = storage_path('documents');
Lists::create(['client_id' => $client_id, 'name' => $name]);
$reader = Reader::createFromPath($file->getRealPath());
// Create a customer from each row in the CSV file
$headers = array();
foreach ($reader as $index => $row)
{
if ($index === 0)
{
$headers = $row;
} else
{
$data = array_combine($headers, $row);
Customers::create($data);
}
}
$file->move($path, $name);
return view('clients');
}
}
CSVファイルを読み取り、Laravelのデータベースにインポートするには3つの手順があります。
開始する前に、サンプル_test.csv
_ファイルを作成し、それをファイルフォルダーの下のパブリックフォルダーに配置しました。
_name,email,password
user1,[email protected],pasxxxxxxxxxword
user2,[email protected],pasxxxxxxxxxword
user3,[email protected],pasxxxxxxxxxword
_
ステップ1と2。 csvToArray
というヘルパー関数を作成しました。とりあえずコントローラーに配置します(この関数はこの link からインスピレーションを受けています)。単純にCSVファイルを読み取り、配列に変換します。
_function csvToArray($filename = '', $delimiter = ',')
{
if (!file_exists($filename) || !is_readable($filename))
return false;
$header = null;
$data = array();
if (($handle = fopen($filename, 'r')) !== false)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== false)
{
if (!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
_
ステップ3;そして、これが私の最後のステップです。配列を読み取り、データベースに挿入します。
_public function importCsv()
{
$file = public_path('file/test.csv');
$customerArr = $this->csvToArray($file);
for ($i = 0; $i < count($customerArr); $i ++)
{
User::firstOrCreate($customerArr[$i]);
}
return 'Jobi done or what ever';
}
_
注:このソリューションは、Laravelプロジェクトにモデルがあり、データベースに適切なテーブルがあることを前提としています。
store()
メソッドで、lists
テーブルにレコードを作成し、CSVファイルの内容を反復処理して、customers
テーブルにデータを挿入します。この目的のために、顧客とリストの間に relation を作成する必要があります。また、 PHPリーグのCSVパッケージ のようなものを使用して、このようなファイルを読み取ることをお勧めします。
public function store(AddCustomersRequest $request)
{
// Get uploaded CSV file
$file = $request->file('csv');
// Create list name
$name = time().'-'.$file->getClientOriginalName();
// Create a list record in the database
$list = List::create(['name' => $name]);
// Create a CSV reader instance
$reader = Reader::createFromFileObject($file->openFile());
// Create a customer from each row in the CSV file
foreach ($reader as $index => $row) {
$list->customers()->create($row);
}
// Redirect back to where you need with a success message
}
@maytham Maythamのソリューションはうまく機能します。ただし、大きなデータを処理しようとすると、大きな問題が発生します。 1000行を実行しても、1000の挿入ステートメントを個別に作成するため、問題が発生します。彼による3番目のメソッドを編集して、独自の入力を追加します。
public function importCsv()
{
$file = public_path('file/test.csv');
$customerArr = $this->csvToArray($file);
$date = [];
for ($i = 0; $i < count($customerArr); $i ++)
{
$data[] = [
'column_name1' => 'value',
'column_name2' => 'value2',
.. so..on..and..on
];
//User::firstOrCreate($customerArr[$i]);
}
DB::table('table_name')->insert($data);
return 'Jobi done or what ever';
}
これは、データベースを1回呼び出して、必要な数の行を挿入します。 1000、100000、その他何でも。 ただし、巨大なcsvがある場合は、チャンクに挿入する必要があるため、これも問題になります。PostgreSQLのように、1つのステートメントに最大65000行を挿入できることに気付きました。私は数について間違っていますが、すべてのデータベースに制限があり、それを探す必要があります。