Mostly everything via composer is determinate, and repeatable. This effect is most of the design spec.
I am not mrZ, but this did happen to me (with a library that I thought always had namespaces, so I was confused by the server2 situation, without them).

Occasional occurrence user story

  • mrZ is a hardworking but hapless dev, work majoring in PHP+frameworks and JS+frameworks or Node +frameworks..
  • On server1 (likely to be local test), he runs `composer require x/x`, and it deploys versionX (what mrZ wants)
  • Does work..
  • On server2 (likely to be UAT), he runs `composer require x/x`, and it deploys versionY
  • Deployment time unit-tests will FAIL.
  • Being short on time, mrZ enables headless-chicken mode and writes to STDERR “omg, its b0rken, OMG!, OMG!"

Solution

#IFDEF LUCKY

  • `composer remove x/x` << to reset, not always needed
  • `composer require x/x XXX` where XXX is the version on the first server

#ELSE

  • create tgz of relevant $projectroot/vendor/x lib on server1, scp it across to server2
  • View server1 $projectroot/install.json, copy section relevant to x/x into server2 instance
  • View server1 $projectroot/composer.lock , copy section relevant to x/x into server2 instance
  • On server2 `composer dump-autoload --optimize`
  • View $projectroot/vendor/composer/autoload_classmap.php, check x appears
  • `php ./bin/console cache:warmup`

#ENDIF

Obviously having a platform that you can update is always valuable, but if the package author has completely changed the package release version in the time it takes to to get a piece of software up to QA, what else can you do?
It is useful to read the section in your composer.json called 'constraints'. Somewhere in composer there is code that chooses which is the best version of PHP to target, and it really likes 5.3.9