Setting Class Properties
Security

Use prepared statements. Classes are reusable, so even if the id is not user provided right now, this may very well change in the future, making your code vulnerable to SQL injection.

Naming

getDetails is rather vague. What details? Additionally, getX usually signals that the method returns X, which isn't the case here. 

Your comment is a bit better, something like assignProperties might work. I would prefer something like loadById, populateById, or more explicit populateFieldsById.

General Structur

getDetails should be private, right?

As for the general structure, it's fine. 

I would probably separate the Foo object from the code retrieving it from the database like this (pseudo code):

// just setters, getters, and business logic
class Foo {

    constructor(...) {...}
    getPropertyX() {...}
    setPropertyX(...) {...}
    getPropertyY() {...}
    setPropertyY(...) {...}
    performSomeBusinesslogicOnObject() {...}

}

// performing database interactions and populating Foo objects
class FooDAO {

    Foo getById(id) {...}
    Foo getByPropertyZ(z) {...}
    save(Foo foo) {...}

}


My main reason for doing it this way is that it separates the database operation from the model. 

Now, you can use the model without being forced to have a database interaction (maybe one isn't needed right now, maybe you want to run tests, maybe the current instance of the object comes from somewhere else than the database, etc).

On the other hand, if most of your business logic happens directly on the database, not the object, this might get confusing. So it really also depends on what Foo is exactly. But for simple objects which are mainly retrieved, updated, saved, etc, this is the way I would go.