Without including require_once __DIR__.'functions.php'; on top of lib/BattleManager.php file, how come the line 19 of lib/BattleManager.php file succeed to be executed ? As the didJediDestroyShipUsingTheForce() function was defined in functions.php ( before moving it to the BattleManager class ), wasn't it supposed to be needed to add require_once __DIR__.'functions.php'; on top of lib/BattleManager.php file ?
You're definitely thinking the correct way. The key is that index.php is the file that's loaded first and it has require __DIR__.'/functions.php'; on the first line. This means that all of those functions are available to any other files for the rest of this request.
But, you do touch on an interesting problem with require. In this case, the didJediDestroyShipUsingTheForce() function is available inside BattleManager.php because an earlier file index.php required it. But... when you look at BattleManager.php, you can't see this - you don't know that this is happening unless you look at the whole request flow. And what if we create another file - otherPage.php - where we don't require functions.php and then we try to use BattleManager? In that case, the function would suddenly not exist inside of BattleManager.
This is a LONG way of saying that require statements can be a bit confusing (do I need a require here or not?) and error-prone. In OO episode 4, we talk about the solution to this: an "autoloader": https://symfonycasts.com/screencast/oo-ep4/autoloading-awesomeness - this is where you basically teach PHP to do the require statements automatically, so you don't need to worry about them.
Do you mean that on the first request (index.php) there is one ShipLoader instance and when you submit the form (battle.php) that creates a second ShipLoader instance? if so, you are 100% correct! We are working with different ShipLoader instances on each request - that's just a property of how php works. So, within a single request, you typically only need one instance of a service (ShipLoader)... because (if you needed to) you could call $shipLoader->getShips() multiple times. But yes, on the next request, all your objects (including your services) will be instantiated fresh. Ideally, your service objects will behave the same each time they are instantiated - i.e. $shipLoader->getShips() will return the same array of Ship objects.
Does that help? Or... did I misunderstand your question entirely? :p
Nice avatar, btw :). You're totally right - the mt_rand() makes this all a bit less realistic, and means that the individual Ship objects on one request won't actually perfectly match the objects on the next request. In a real app, where we would probably load all this data from the database, the Ship objects would have identical data between the requests (even though they are technically different instances in memory) because they would be loading data from the same place (and no randomness).
7 Comments
Without including require_once __DIR__.'functions.php'; on top of lib/BattleManager.php file, how come the line 19 of lib/BattleManager.php file succeed to be executed ? As the didJediDestroyShipUsingTheForce() function was defined in functions.php ( before moving it to the BattleManager class ), wasn't it supposed to be needed to add require_once __DIR__.'functions.php'; on top of lib/BattleManager.php file ?
Yo Tariq I.!
You're definitely thinking the correct way. The key is that
index.phpis the file that's loaded first and it hasrequire __DIR__.'/functions.php';on the first line. This means that all of those functions are available to any other files for the rest of this request.But, you do touch on an interesting problem with
require. In this case, thedidJediDestroyShipUsingTheForce()function is available insideBattleManager.phpbecause an earlier fileindex.phprequired it. But... when you look atBattleManager.php, you can't see this - you don't know that this is happening unless you look at the whole request flow. And what if we create another file -otherPage.php- where we don't requirefunctions.phpand then we try to useBattleManager? In that case, the function would suddenly not exist inside ofBattleManager.This is a LONG way of saying that require statements can be a bit confusing (do I need a require here or not?) and error-prone. In OO episode 4, we talk about the solution to this: an "autoloader": https://symfonycasts.com/screencast/oo-ep4/autoloading-awesomeness - this is where you basically teach PHP to do the require statements automatically, so you don't need to worry about them.
I hope that helps!
Cheers!
Hi, You used two instances of the ShipLoader, so you might be battling ships that are on service. Right?
Hey Simón B.!
Do you mean that on the first request (index.php) there is one ShipLoader instance and when you submit the form (battle.php) that creates a second ShipLoader instance? if so, you are 100% correct! We are working with different ShipLoader instances on each request - that's just a property of how php works. So, within a single request, you typically only need one instance of a service (ShipLoader)... because (if you needed to) you could call
$shipLoader->getShips()multiple times. But yes, on the next request, all your objects (including your services) will be instantiated fresh. Ideally, your service objects will behave the same each time they are instantiated - i.e.$shipLoader->getShips()will return the same array of Ship objects.Does that help? Or... did I misunderstand your question entirely? :p
Cheers!
But doesn't that change the underRepair property of the ship objects, as this property exploits the mt_rand() function ?
Yo Tariq I.!
Nice avatar, btw :). You're totally right - the
mt_rand()makes this all a bit less realistic, and means that the individualShipobjects on one request won't actually perfectly match the objects on the next request. In a real app, where we would probably load all this data from the database, theShipobjects would have identical data between the requests (even though they are technically different instances in memory) because they would be loading data from the same place (and no randomness).So, yea, you're definitely thinking correctly!
Cheers!
Good tip! I didn't show that here because I want them to understand what changes and why. But in real life, I absolutely use this :).
"Houston: no signs of life"
Start the conversation!