Q:

doctrine entities implementing interface in order to typehint

I am trying to create a way to upload files. There are two types of files that can be uploaded: GPS files and media files. They're very similar but store slightly different information. A service handles their upload. But because I want the service's upload function to work with correctly typehinted arguments, I created a FileInterface that both GpsFile and MediaFile implement. But does this still make sense for symfony/doctrine entities?
interface FileInterface {

}

class MediaFile implements FileInterface {
    private $id;
    private $orientation;
}

class GpsFile implements FileInterface {
    private $id;
    private $date;
}

class FileUploaderService {
    public
    function upload(FileInterface $file) {
        // code to upload
    }
}

A:

Your approach is absolutely correct for achieving type-hinting. If the uploaded files are stored in the database and accessed using Doctrine/Entities, then you may want to consider the approach to handle such in Doctrine.
1. Single table inheritance
If the different types of uploads mostly have similar fields to be stored in the database and if you are fine with delegating the proper handling required/nullable fields on the Symfony side, this is a good option given your usecase. With this approach, Doctrine stores all the fields for File, Media and GPS are stored in the same table and uses a combination of the discriminator field and fields for other inheriting entities set to NULL.
You'd then have something like the following for the entities:
Base File entity declared as abstract:
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\FileRepository")
 * @ORM\Table(name="file")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({
 *     "media" = "Media",
 *     "gps" = "Gps"
 * })
 */
abstract class File
{
    // Properties, ORM column mappings, assertions and getters/setters for Id, filename, mimetype and other common fields needed for the file uploads...
}

Entity for Media extending File
/**
 * Media
 *
 * @ORM\Entity(repositoryClass="AppBundle\Repository\MediaRepository")
 */
class Media extends File
{
    // Media Upload specific properties, ORM column mappings etc...
}

Entity for GPS extending File
/**
 * GPS
 *
 * @ORM\Entity(repositoryClass="AppBundle\Repository\GpsRepository")
 */
class Gps extends File
{
    // Gps Upload specific properties, ORM column mappings etc...
}

For type-hinting, then you can have the abstract File class implement your FileInterface and do the same for Media and Gps entities, or better yet, have other interfaces specific to Media and Gps that defines their own interface and extends the FileInterface.
2. Class table inheritance.
If the Media/Gps entities have a lot of fields unique to each then it maybe better to use class inheritance, which would create a parent table for File and a table for each of Media and Gps, linking them through foreign key relationship and discriminator field. This has performance hits due to reliance on JOIN calls. see Doctrine docs

