ChatGPT解决这个技术问题 Extra ChatGPT

Eloquent ->first() if ->exists()

I want to get the first row in table where condition matches:

User::where('mobile', Input::get('mobile'))->first()

It works well, but if the condition doesn't match, it throws an Exception:

ErrorException
Trying to get property of non-object

Currently I resolve it like this:

if (User::where('mobile', Input::get('mobile'))->exists()) {
    $user = User::where('mobile', Input::get('mobile'))->first()
}

Can I do this without running two queries?

I don't know what version of Laravel you were using, but first() doesn't throw an exception if the table doesn't have matching rows, and I know it hasn't since at least Laravel 4.2. It just returns null. It may be that the exception was caused by a different issue with your code.
I think you may need to include your User model, use App\Models\User; if you don't have it on your controller. That may be causing the exception

o
orrd

Note: The first() method doesn't throw an exception as described in the original question. If you're getting this kind of exception, there is another error in your code.

The correct way to user first() and check for a result:

$user = User::where('mobile', Input::get('mobile'))->first(); // model or null
if (!$user) {
   // Do stuff if it doesn't exist.
}

Other techniques (not recommended, unnecessary overhead):

$user = User::where('mobile', Input::get('mobile'))->get();

if (!$user->isEmpty()){
    $firstUser = $user->first()
}

or

try {
    $user = User::where('mobile', Input::get('mobile'))->firstOrFail();
    // Do stuff when user exists.
} catch (ErrorException $e) {
    // Do stuff if it doesn't exist.
}

or

// Use either one of the below. 
$users = User::where('mobile', Input::get('mobile'))->get(); //Collection

if (count($users)){
    // Use the collection, to get the first item use $users->first().
    // Use the model if you used ->first();
}

Each one is a different way to get your required result.


the first line throws exception as I said, if the no result found.
@Webinan This version should always return an Eloquent\Collection, allowing you to always call the method isEmpty() on it.
YES, Thanks, (... and then I should get the first row using $user->first() )
so first() does not return a collection?
@dangel No first() will not return a Collection this will return the first Model object from the initial Collection, if there is one.
A
Ash

(ps - I couldn't comment) I think your best bet is something like you've done, or similar to:

$user = User::where('mobile', Input::get('mobile'));
$user->exists() and $user = $user->first();

Oh, also: count() instead if exists but this could be something used after get.


thanks for your comment :) see Matt's answer that's the way to go, in my code queries to the db is doubled and inefficient.
J
Jarek Tkaczyk

get returns Collection and is rather supposed to fetch multiple rows.

count is a generic way of checking the result:

$user = User::where(...)->first(); // returns Model or null
if (count($user)) // do what you want with $user

// or use this:
$user = User::where(...)->firstOrFail(); // returns Model or throws ModelNotFoundException

// count will works with a collection of course:
$users = User::where(...)->get(); // returns Collection always (might be empty)
if (count($users)) // do what you want with $users

Your first example isn't correct because first() returns either one object or null. You shouldn't call count() on it. For the 3rd example, you can use count() in that case, but it's probably best to use $users->count().
@orrd yes, it returns model or null. Why is it the easiest way? See stackoverflow.com/a/23911985/784588 It is, obviously, correct. One may say it is indirect, but that different story.
R
Rashi Goyal

Try it this way in a simple manner it will work

$userset = User::where('name',$data['name'])->first();
if(!$userset) echo "no user found";

u
user1669496

An answer has already been accepted, but in these situations, a more elegant solution in my opinion would be to use error handling.

    try {
        $user = User::where('mobile', Input::get('mobile'))->first();
    } catch (ErrorException $e) {
        // Do stuff here that you need to do if it doesn't exist.
        return View::make('some.view')->with('msg', $e->getMessage());
    }

Hmm, yes of course that's why exceptions exist! But I needed to know how to this specifically with Eloquent methods. Thanks
first() does not throw an Exception, it returns null if nothing is found so this will not work. The proper method to use is firstOrFail() which is referenced in the accepted answer.
In the question, it is stated an ErrorException is thrown if the condition does not match so I assumed something was being overridden.
The original question made an in incorrect assumption (or they were using a very early version of Laravel before Laravel 4).