Laravel: Eloquent all() ไม่ส่งคืนอาร์เรย์ของวัตถุ

ฉันกำลังพยายามสร้างระบบฟอรัมที่เรียบง่าย

ฉันมีโมเดลชื่อ Category.php ซึ่งฉันกำหนดตารางและขยาย Eloquent

ฉันมี CategoryController.php ซึ่งเป็นตัวควบคุมที่เชี่ยวชาญ ภายในเมธอด index() ฉันกำลังทำ:

$categories = Category::all();

ซึ่งฉันคิดว่าควรส่งคืนอาร์เรย์ของวัตถุ สิ่งนี้ใช้ได้ดีกับโปรเจ็กต์อื่นของฉัน

อย่างไรก็ตาม เมื่อฉันพยายามเรียกใช้สิ่งนี้ผ่าน foreach ก็ไม่มีอะไรสะท้อนกลับ ฉันได้ลองเปลี่ยนชื่อคอนโทรลเลอร์และโมเดลเป็น ForumController และ Form ตามลำดับ และมันก็ใช้งานได้ทันที

มีความคิดอะไรบ้าง? บางทีชื่อหมวดหมู่อาจถูกสงวนไว้โดย Laravel และกำลังแทนที่ฟังก์ชันการทำงานที่ฉันต้องการ

CategoryController.php:

<?php

class CategoryController extends \BaseController {

protected $layout = 'master';

/**
 * Display a listing of the resource.
 *
 * @return Response
 */
public function index()
{
    //
    $categories = Category::all();
    $this->layout->content = View::make('category.index', array('categories' => $categories));
}

Category.php (รุ่น):

<?php

class Category extends Eloquent {

/**
 * The database table used by the model.
 *
 * @var string
 */
protected $table = 'categories';

}

Category/index.blade.php (ดู):

@section('content')
<ul>
@foreach ($categories as $category)
    <li><a href="/th/category/{{ $category->slug }}">{{ $category->name }}</a></li>
@endforeach
</ul>
@stop

ฐานข้อมูลของฉันได้รับการตั้งค่าอย่างถูกต้อง เมื่อฉันเรียกใช้ $category = Category::find(1); มันส่งคืนหมวดหมู่อย่างถูกต้องด้วยรหัส 1 ซึ่งฉันสามารถใช้เป็นวัตถุได้


person Karl    schedule 16.02.2014    source แหล่งที่มา
comment
รู้สึกเหมือนคุณไม่ได้ ลอง foreach ไปกับคอลเลกชั่นเลยด้วยซ้ำ เพราะถ้าคุณมี คุณจะพบว่ามันได้ผล   -  person alexrussell    schedule 16.02.2014
comment
ไม่หรอก เพราะฉันไม่รู้ว่าคอลเลกชั่นต่างๆ ทำงานภายใน Laravel อย่างไร ดังนั้นฉันจึงถามที่นี่ แล้วมันรับประกันการลงคะแนนเสียงได้อย่างไร   -  person Karl    schedule 16.02.2014
comment
ขออภัยที่คุณรู้สึกเช่นนั้น การลงคะแนนเสียงลงเป็นเพราะโดยสุจริตฉันไม่คิดว่ามันเป็นคำถามที่เป็นประโยชน์ต่อชุมชน SO ตัวคำถามมีข้อบกพร่องตรงที่คุณบอกว่าฉันไม่สามารถเผยแพร่คอลเลกชั่นได้ ทั้งที่จริงๆ แล้วคุณสามารถทำได้ ดังนั้นจึงอาจทำให้ผู้อื่นในเครือข่ายเข้าใจผิดได้ (แหล่งที่มาสำหรับเหตุผลเบื้องหลัง downvote ตามด้านบนที่: stackoverflow.com/help/privileges/vote-down)   -  person alexrussell    schedule 16.02.2014
comment
ไม่จริง เนื่องจากฉันพยายามเรียกใช้ foreach แต่ไม่มีผลลัพธ์ ดังนั้นฉันจึงโพสต์ที่นี่เพื่อขอคำแนะนำ จากนั้น ฉันเปลี่ยนชื่อจากหมวดหมู่เป็นฟอรัม และใช้งานได้ดี ดังที่คุณสามารถบอกได้จากความคิดเห็นในคำตอบอื่นๆ ซึ่งทำให้ฉันเชื่อว่า Category นั้นถูกสงวนไว้หรืออะไรสักอย่าง เนื่องจากมันไม่ได้ผลตามที่คาดไว้   -  person Karl    schedule 16.02.2014
comment
ในกรณีนี้ อาจคุ้มค่าที่จะแก้ไขคำถามของคุณเพื่อแสดงโค้ดที่คุณพยายามเรียกใช้ foreach (แทนที่จะเป็น dd ซึ่งไม่ค่อยทำงานเหมือนกับที่สามารถตรวจสอบคุณสมบัติส่วนตัวและการป้องกันของวัตถุได้ และไม่ใช่ เวทย์มนตร์) เพื่อให้ผู้อื่นสามารถดูว่ามีปัญหากับโค้ด foreaching จริงของคุณหรือไม่   -  person alexrussell    schedule 16.02.2014
comment
ยุติธรรม แต่ฉันยังไม่คิดว่ามันสมควรที่จะลงคะแนนเสียง อย่างไรก็ตาม ฉันเชื่อว่าการใช้ Category เป็นชื่อสำหรับโมเดลและคอนโทรลเลอร์เป็นปัญหา เนื่องจากนั่นเป็นสิ่งเดียวที่แตกต่างระหว่างโปรเจ็กต์ของฉัน   -  person Karl    schedule 16.02.2014
comment
ฉันไม่คิดว่านี่เป็นเพราะการใช้ Category เป็นชื่อรุ่น - ลองพูดแบบนี้สิ แอป Laravel อย่างน้อย 25% ที่นั่นอาจมีโมเดล Category - แต่อาจเป็นเพราะรหัสของคุณในบริบทที่กว้างขึ้น เป็นเรื่องดีที่คุณแก้ไขโพสต์ของคุณแล้ว แต่คุณยังคงไม่ให้รหัสที่ตรงกันซึ่งใช้ไม่ได้ในรูปแบบ foreach - จะเป็นประโยชน์มากสำหรับเราที่จะเห็นโค้ดนั้น เผื่อว่ายังมีบางอย่างแปลก ๆ อยู่ที่นั่น ฉันรู้ว่าคุณบอกว่าการเปลี่ยนไปใช้รุ่นอื่นก็ใช้ได้ดี แต่ทำไมไม่ลองจัดเตรียมมันดูล่ะ?   -  person alexrussell    schedule 16.02.2014
comment
นอกจากนี้ FYI ฉันจะเพิกถอน downvote ของฉันอย่างมีความสุข (สมมติว่า SO อนุญาต) เมื่อคำถามได้รับการเคลียร์อย่างเพียงพอ ฉันไม่ได้พยายามจับคุณเรียกค่าไถ่ที่นี่จากการโหวตลงคะแนน - คุณสามารถทำสิ่งที่คุณต้องการด้วยคำถามของคุณ - แค่อธิบายความคิดส่วนตัวของฉันในเรื่องเหล่านี้   -  person alexrussell    schedule 16.02.2014
comment
ตอนนี้ฉันได้แก้ไขอีกครั้งพร้อมข้อมูลทั้งหมดที่คุณต้องการ รวมถึงมุมมองในครั้งนี้ที่ฉันเรียกใช้ foreach จริงๆ   -  person Karl    schedule 16.02.2014
comment
ฉันไม่อยากจะแสดงความคิดเห็นมากมายที่นี่ แต่เราต้องการข้อมูลเพิ่มเติม สิ่งนี้ล้มเหลวได้อย่างไร? ไม่มีการพิมพ์ใด ๆ (เช่น foreach ($categories) ดูเหมือนจะไม่ได้รับการวนซ้ำเพียงครั้งเดียว) หรือพิมพ์ HTML แต่ฟิลด์ในแต่ละ $category ไม่ออกมา นอกจากนี้ คุณไม่มีรหัสเช่น View::share('categories', $someValue) ที่ไหนเลยใช่ไหม นั่นอาจเป็นเหตุผลเบื้องหลังชื่อตัวแปรที่สงวนไว้อย่างเห็นได้ชัด   -  person alexrussell    schedule 17.02.2014


คำตอบ (2)


คุณสามารถทำซ้ำมากกว่า Category::all(); คลาส Laravels Collection ใช้อินเทอร์เฟซต่อไปนี้:

ArrayAccess, ArrayableInterface, Countable, IteratorAggregate, JsonableInterface

ซึ่งหมายความว่า:

foreach(Category::all() as $category) { 
    var_dump($category);
}

จะใช้งานได้ Eloquent\Collection ที่ส่งคืนจะขยายคลาส Support\Collection ซึ่งใช้อินเทอร์เฟซข้างต้น

ดูคลาส Support\Collection ใน Illuminate

person SamV    schedule 16.02.2014

คุณพูดถูกแล้ว เมื่อส่งคืนผลลัพธ์หลายรายการ Eloquent จะส่งกลับ Collection (ซึ่งเป็นแนวทางปฏิบัติทั่วไปในกรอบงาน)

คุณสามารถแปลง Collection เป็นรูปแบบอื่นโดยใช้วิธีการเช่น toArray() หรือ toJson(); แต่คุณยังสามารถวนซ้ำผลลัพธ์ count() โดยใช้วิธีเช่น fetch() หรือดึงข้อมูลเฉพาะรายการโดยใช้ get()

แก้ไข

แม้ว่าคุณจะไม่สามารถวนซ้ำบน Collection ได้โดยตรง แต่คุณสามารถแปลงเป็นโครงสร้างที่สามารถวนซ้ำได้โดยใช้เมธอด getIterator() ซึ่งจะส่งคืน SPL ArrayIterator วัตถุ

person Mark Baker    schedule 16.02.2014
comment
อ่าใช่ มันสมเหตุสมผลแล้ว สิ่งเดียวที่ทำให้ฉันงงคือในอีกโปรเจ็กต์ที่ฉันได้ทำสิ่งเดียวกันทุกประการ และฉันสามารถใช้ foreach ทำตามที่ฉันต้องการได้ โดยไม่ต้องใช้วิธีอย่าง toArray() ฉันสงสัยมากว่าทำไมและอะไรทำให้เกิดความแตกต่างนี้ - person Karl; 16.02.2014
comment
ฉันเพิ่งคัดลอกโมเดลและคอนโทรลเลอร์ เปลี่ยนชื่อสำหรับ Category เป็น Forum และมันทำงานได้ดีโดยการเรียก $forums = Forum::all() และเรียกใช้ foreach บนตัวแปร $forums ดังนั้นอาจเป็นไปได้ว่า Laravel อาจสงวนชื่อหมวดหมู่ไว้หรือไม่ ฉันไม่ค่อยแน่ใจ - person Karl; 16.02.2014