Laravel Call to a member function on a non-object

14,853

Solution 1

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.

Solution 2

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
}
Share:
14,853
Rafael
Author by

Rafael

https://rlc.ninja/

Updated on June 27, 2022

Comments

  • Rafael
    Rafael almost 2 years

    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);
    }