我有两种方法可以处理excel电子表格的导入,清理字段(即将“player_name”更改为“name”),过滤掉无效的数据行和有效的数据行。如果存在无效数据,则返回到Vue组件,这使用户有机会更正无效数据。
初始提交由AdminImportPlayersController@store
处理,后续提交(以修复无效数据)由AdminImportFixedPlayersController@store
处理。
数据collect
在发布时加入Collection
。
初始提交由AdminImportPlayersController@store
处理(实际导入excel文件),我可以使用对象语法(即Collection
)访问obj->prop
中的数据。但是,在AdminImportFixedPlayersController@store
控制器中使用基本相同的代码(仍然需要重构,可能将功能体抽象为Facade。)将“对象”视为array
。显然它实际上是array
,但我还没弄清楚为什么会这样......
控制器发布在下面。
AdminImportPlayersController@store
:
/**
* Imports players from an excel spreadsheet.
* Returns invalid players, if present.
*
* Teams are represented by their name in the submitted file.
*
* @param App\HttpRequests\StoreImportPlayersFormRequest $request
* @return Illuminate\Http\Response
*/
public function store(StoreImportPlayersFormRequest $request)
{
$now = Carbon::now()->toW3cString();
$fileName = 'players-import-' . $now . '.xls';
// moving imported file to local storage
$request->file('players')->move(storage_path('/import/excel/'), $fileName);
// creating a Collection from the results returned from file
$player_data = collect(Excel::load(storage_path('import/excel/') . $fileName)->get());
// clean up data structure
$player_data = $player_data->map(function ($player) {
$player['name'] = $player->player_name;
unset($player['player_name']);
return $player;
});
// get all invalid entries
$invalid_player_data = $player_data->filter(function ($player) {
\Log::info($player);
return ! Team::where('name', $player->team)->first() || $player->name == null;
})->values();
// get all valid entries
$valid_player_data = $player_data->filter(function ($player) {
return Team::where('name', $player->team)->first() && $player->name !== null;
})->values();
// save players
$valid_player_data->each(function ($player) {
$team = Team::where('name', $player->team)->first();
$team->players()->attach(
Player::create([
'name' => $player->name,
'temp' => 0,
])
);
});
return response()->json(['invalid_player_data' => $invalid_player_data->all()], 200);
}
AdminImportFixedPlayersController@store
:
/**
* Stores fixed player data, after re-submission due to invalid data.
* Returns invalid players, if still present.
* Teams are represented by their id.
*
* @param App\Http\Requests\StoreImportFixedPlayersFormRequest $request
* @return Illuminate\Http\Response
*/
public function store(StoreImportFixedPlayersFormRequest $request)
{
$player_data = collect($request->players);
// get all invalid entries
$invalid_player_data = $player_data->filter(function ($player) {
return ! Team::where('id', $player['team'])->first() || $player['name'] == null;
})->values();
// get all valid entries
$valid_player_data = $player_data->filter(function ($player) {
return Team::where('id', $player['team'])->first() && $player['name'] !== null;
})->values();
// save players
$valid_player_data->each(function ($player) {
$team = Team::where('id', $player['team'])->first();
$team->players()->attach(
Player::create([
'name' => $player['name'],
'temp' => 0,
])
);
});
return response()->json(['invalid_player_data' => $invalid_player_data->all()], 200);
}
请注意说
之类的内容return ! Team::where('id', $player->team)->first() || $player->name == null;
在AdminImportPlayersController
(处理初始导入的控制器)中,它是合法的,不会抛出任何异常。
但是,相同的代码在AdminImportFixedPlayersController
中使用时会引发异常,我只能合法地使用以下语法:
return ! Team::where('id', $player['team'])->first() || $player['name'] == null;
对于冗长的问题感到抱歉,就像要彻底!
如果需要,请询问更多信息。
我已在不同位置的两种方法中注销$player_data
的值。从请求中收集后,$player_data
中AdminImportFixedPlayersController
的值等于:
[{"name": "ashley", "team" : 1}, ..., ...].
为什么我不能在不使用类似数组的语法的情况下访问这些对象的属性?
答案 0 :(得分:0)
从$request->players
$player_data = collect($request->players);
我将每个Player
映射到自己的Collection
以及$ player_data中的每个Player
,将每个Player
上的属性设置为等于相关数据的值,访问作为普通数组:$player->name = $player['name'];
。
解决方案:
$player_data = collect($request->players);
// turn each 'player' into a collection and create properties that are accessible via object->method notation
$player_data = $player_data->map(function ($player) {
$player = collect($player);
$player->name = $player['name'];
$player->team = $player['team'];
return $player;
});