I have a class named Locations, it should accept 3 parameters name, city_id, country_id.
What is the best solution for passing these values, should i pass variables or instances of their classes.
$location = new Locations('Dubai, UAE', 1, 2);
$location = new Locations('Dubai, UAE', $cityId, $countryId);
I believe for the sake of clarity and the single responsibility i should use dependency injection
$location = new Locations('Dubai, UAE', new City('Dubai'), new Country('UAE'));
When and why should i use variables (IDs) instead of instances?
When and why should i use variables (IDs) instead of instances?
That is a question of the design of your application and it can greatly differ in which layer you are.
For example for manipulating a recordset in the database, you might just need the id value (non-zero, positive integer) to perform an operation on a specific recordset. In such a case you would need the ID.
A Location on the other hand might not even need the ID to operate.
As one design goal might (should) be, to do as little as necessary, I'd say you don't pass the ID-values to the Location constructor as it otherwise would be dependent on the whole system in which these ids are coming from (e.g. the database). That would couple the database layer and even the database itself to the Location class.
But the Location class should work without caring about the database at all. At least if so, you can make more flexible use out of it, which allows you to develop further.
This are just some generic pointers. It can be even more implementation specific like when creating something similar to what is outlined in Flyweight Pattern.
So you should better ask and test your design that it does as little as necessary to do the job.
There can be performance reasons for example, it's much faster to create and pass around integer values (IDs) than to instantiate and pass around object values (objects), but not always and it can be even negligible.
Some things I'd like to clarify and comment on in context of your question and my answer:
Variables can be both IDs (values) or instances. Technically an object variable in PHP is just like an ID, it contains the ID (reference) of the actual object in memory.
You can treat a constructor as implementation detail. That done, it is easy to change it later which allows you to defer the details.
I named it Location class as it is singular. The name of the class should be representative and not mislead. Locations sounds like a collection of zero or more Location objects.
This question can't be fully answered as it depends on so many things. To better make up your mind also consider the other answer which shows some more decision making points.