Rafael
Rafael

Reputation: 7746

Laravel Call to a member function on a non-object

I have searched on stack and found many questions like this...

However, I am sure that I am using an object and have verified that in the dump.

Error

>16: Call to a member function getRealPath() on a non-object

Line 16

$image->getRealPath();

Var Dump $image

object(Symfony\Component\HttpFoundation\File\UploadedFile)#9 (7) { ["test":"Symfony\Component\HttpFoundation\File\UploadedFile":private]=> bool(false) ["originalName":"Symfony\Component\HttpFoundation\File\UploadedFile":private]=> string(41) "5a862f92da957da3e0208357ce006afd_970x.jpg" ["mimeType":"Symfony\Component\HttpFoundation\File\UploadedFile":private]=> string(10) "image/jpeg" ["size":"Symfony\Component\HttpFoundation\File\UploadedFile":private]=> int(346047) ["error":"Symfony\Component\HttpFoundation\File\UploadedFile":private]=> int(0) ["pathName":"SplFileInfo":private]=> string(24) "C:\xampp\tmp\phpA5C7.tmp" ["fileName":"SplFileInfo":private]=> string(11) "phpA5C7.tmp" } 

If I dump $image->getRealPath(); I get a string(24) "C:\xampp\tmp\phpE193.tmp" which is what I want. I have no idea why it's saying $image is not an object when clearly it is.

Controller

# Process Images - Queue?
if ($filesUploaded) {
    $images = Input::file('images');
    foreach ($images as $image) {
        # Record Creation
        $record = new Image;
        $record->user_id = Auth::id();
        $record->ad_id = $adId;
        $record->name = Str::random();
        $record->save();
        # Create TN
        $record->createTN($image);
        # Create Smalls
        # Create Larges
    }
}

Image class

public function createTN($image) {
    $PUBLIC_PATH = public_path();

# Load Zebra Image Library
require_once $PUBLIC_PATH.'/uploads/Zebra_Image.php';

$destinationPath = $PUBLIC_PATH.'/uploads/thumbnails/';
$tn = new Zebra_Image();
$tn->source_path = $image->getRealPath();
$tn->target_path = $destinationPath.$this->name.'_sm.jpg';
$tn->jpeg_quality = 60;
$tn->preserve_aspect_ratio = true;
$tn->enlarge_smaller_images = true;
$tn->resize(100, 100, ZEBRA_IMAGE_CROP_CENTER);
}

Upvotes: 3

Views: 15127

Answers (2)

Alana Storm
Alana Storm

Reputation: 166046

Looking at the original loop

$images = Input::file('images');
foreach ($images as $image) {
    # Record Creation
    $record = new Image;
    $record->user_id = Auth::id();
    $record->ad_id = $adId;
    $record->name = Str::random();
    $record->save();
    # Create TN
    $record->createTN($image);
    # Create Smalls
    # Create Larges
}

It looks like you're processing a request with more than a single file upload. The form, javascript code, or flash uploader code you're using to post to this Laravel route looks like it's sending at least one file (or perhaps a blank file entry) that Laravel's request object can't process into an object. A loop like this might reveal more about what's going on

foreach($images as $image)
{
    var_dump($image);
}

Most of those will be Symfony\Component\HttpFoundation\File\UploadedFile objects, but I bet at least one of them is a null. You could also try var_dump($_FILES) and look for any obvious errors or empty entries -- maybe something that's too large for the server to process?

The reason you couldn't use lukasgeiter's solution is the Symfony\Component\HttpFoundation\File\UploadedFile class has PHP's internal SplFileInfo class as an ancsetor, and until very recently PHP had a bug/feature where a programmer couldn't cast SplFileInfo as a boolean (using the using ! converts the variable to a boolean type for the comparision)

Finally, Laravel relies on Symfony components for its file upload functionality. I believe you can find the Symfony\Component\HttpFoundation\File\UploadedFile instantiations here

#File: vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/FileBag.php
protected function convertFileInformation($file)
{
    if ($file instanceof UploadedFile) {
        return $file;
    }

    $file = $this->fixPhpFilesArray($file);
    if (is_array($file)) {
        $keys = array_keys($file);
        sort($keys);

        if ($keys == self::$fileKeys) {
            if (UPLOAD_ERR_NO_FILE == $file['error']) {
                $file = null;
            } else {
                $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']);
            }
        } else {
            $file = array_map(array($this, 'convertFileInformation'), $file);
        }
    }

    return $file;
}

So if you're a debug at the source sort of person, start here.

Upvotes: 3

lukasgeiter
lukasgeiter

Reputation: 152860

One of your images probably is not set. So when you check (the first) with a var_dump everything seems alright. But when the full loop runs it throws an exception on the second, third, ... iteration.

This should fix it:

foreach ($images as $image) {
    if(!is_object($image)) continue;
    # Record Creation
    $record = new Image;
    $record->user_id = Auth::id();
    $record->ad_id = $adId;
    $record->name = Str::random();
    $record->save();
    # Create TN
    $record->createTN($image);
    # Create Smalls
    # Create Larges
}

Upvotes: 2

Related Questions