NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #3154 most downloaded on Packagist
An implementation of the 3D (actually 4D) bin packing/knapsack problem (aka creating parcels by putting items into boxes)
Last release 1 months ago
09 Aug 2026
Ships fairly regularly
a new release about every 5 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
13 years old
93 releases · first in 2013
In some rare cases WeightRedistributor would silently drop items
WeightRedistributor would silently drop itemsA mechanism to allow forcing certain items to be packed together [RubenKluft]
One column per quarter.
In some cases the maximum weight of a box was not respected
A mechanism to allow a proactive timeout on v. large packings rather than run to completion
Changed Improved efficiency in packing
Removed deprecated ConstrainedItem . You should use ConstrainedPlacementItem as a replacement
Rotation with values Never, KeepFlat and BestFitgetAllowedRotation() method to the Item interface to replace getKeepFlat(). This should returnRotation enum valuesgenerateVisualisationURL() method to PackedBox and PackedBoxList. This will generate a custom URL forpackAllPermutations() method to Packer to calculate all possible box combinationsthrowOnUnpackableItem() to Packer to control if an exception is thrown (or not) if an unpackable item isgetUnpackedItems() to Packer to retrieve the list of items that could not be packed (only applicable ifPackedBox now has readonly public properties ->box and ->itemPackedItem now has readonly public properties ->item, ->x, ->y, ->z, ->width, ->length, ->depthDVDoug\BoxPacker\Exception namespace (previously DVDoug\BoxPacker)->canBePacked method on the ConstrainedPlacementItem interface has been changed to replace theBox $box, PackedItemList $alreadyPackedItems) with PackedBox $packedBox. This allowsPackedBox. Access to the box and items can be done via$packedBox->box and $packedBox->itemsNoBoxesAvailableException now has a ->getAffectedItems() method instead of ->getItem(). This should allowgetBox() and getItems() from PackedBox. Use the new public properties instead->getItem(), ->getX(), ->getY(), ->getZ(), ->getWidth(), ->getLength() and ->getDepth()PackedItem. Use the new public properties insteadConstrainedItem. You should use ConstrainedPlacementItem as a replacementgetKeepFlat() from the Item interfaceInfalliblePacker. You can now get the same behaviour by calling ->throwOnUnpackableItem(false) and->getUnpackedItems() on the main Packer classRotation with values Never, KeepFlat and BestFitgetAllowedRotation() method to the Item interface to replace getKeepFlat(). This should return
one of the new Rotation enum valuesgenerateVisualisationURL() method to PackedBox and PackedBoxList. This will generate a custom URL for
a visualisation you can access via the BoxPacker websitepackAllPermutations() method to Packer to calculate all possible box combinationsthrowOnUnpackableItem() to Packer to control if an exception is thrown (or not) if an unpackable item is
found (defaults to true, consistent with previous behaviour)getUnpackedItems() to Packer to retrieve the list of items that could not be packed (only applicable if
exceptions are disabled)PackedBox now has readonly public properties ->box and ->itemPackedItem now has readonly public properties ->item, ->x, ->y, ->z, ->width, ->length, ->depthDVDoug\BoxPacker\Exception namespace (previously DVDoug\BoxPacker)->canBePacked method on the ConstrainedPlacementItem interface has been changed to replace the
first two arguments(Box $box, PackedItemList $alreadyPackedItems) with PackedBox $packedBox. This allows
callbacks to make use of the helper methods provided on PackedBox. Access to the box and items can be done via
$packedBox->box and $packedBox->itemsNoBoxesAvailableException now has a ->getAffectedItems() method instead of ->getItem(). This should allow
improved handling of the exception inside calling applications when multiple items cannot be packedgetBox() and getItems() from PackedBox. Use the new public properties instead->getItem(), ->getX(), ->getY(), ->getZ(), ->getWidth(), ->getLength() and ->getDepth()
from PackedItem. Use the new public properties insteadConstrainedItem. You should use ConstrainedPlacementItem as a replacementgetKeepFlat() from the Item interfaceInfalliblePacker. You can now get the same behaviour by calling ->throwOnUnpackableItem(false) and
->getUnpackedItems() on the main Packer classRestored ability to copy/paste the samples from the docs into a non-dev installation
Support for PHP 7.1, 7.2 and 7.3
Calling json_encode() on a PackedBox or PackedItem now additionally serialises the entire underlying Box / Item where those objects also implement Jso
json_encode() on a PackedBox or PackedItem now additionally serialises the entire underlyingBox/Item where those objects also implement JsonSerializable. Previously the serialisation only included theBox/Item interfaces themselves.Added ItemSorter , BoxSorter and PackedBoxSorter to allow calling applications to have better control over sorting decisions
ItemSorter, BoxSorter and PackedBoxSorter to allow calling applications to have better control overbeStrictAboutItemOrdering() to Packer and VolumePackerpsr/log compatibility changed from ^1.0 to ^1.0||^2.0||^3.0
psr/log compatibility changed from ^1.0 to ^1.0||^2.0||^3.0### Fixed - PHP8.1 deprecations
Optional second parameter $qty to ItemList->insert()
$qty to ItemList->insert()Fixed issue where available width for an item could be miscalculated at the far end of a box
Added packAcrossWidthOnly() to VolumePacker for scenarios where the container will be side-loaded rather than top-loaded (e.g. truck loading)
packAcrossWidthOnly() to VolumePacker for scenarios where the container will be side-loaded rather
than top-loaded (e.g. truck loading)getWeight() helper method to PackedItemListAdded fromArray() helper method to BoxList to make bulk add easier [bram123]
fromArray() helper method to BoxList to make bulk add easier [bram123]Added getVolume() helper method to PackedItemList
getVolume() helper method to PackedItemList### Added - Support for PHP 8.0
Fixed situation where internal WorkingVolume could be passed into a constraint callback, rather than the calling application's own Box
WorkingVolume could be passed into a constraint callback, rather than the calling application's own BoxImproved efficiency in packing and weight distribution
@internal classes or made use of @internal methods you may be affected.Further optimisation when packing a large number of items
Optimisation when packing a large number of identical items
Added a new interface LimitedSupplyBox extends Box for situations where there are restrictions on the number of a box type available for packing Items
LimitedSupplyBox extends Box for situations where there are restrictions on the number of a box type available for packing Items into. The interface contains 1 additional method getQuantityAvailable().NoBoxesAvailableException which is thrown when an item cannot be packed due to suitable boxes not being available (e.g. when the new functionality is used and the quantity available is insufficient). The existing ItemTooLargeException which is thrown when an item is too large to fit into any of the supplied box types at all (regardless of quantity) still exists, and now extends from NoBoxesAvailableException as a special caseItemList passed to VolumePacker's constructor is now cloned before usage, leaving the passed-in object unaffected. Previously this was used as a working dataset. The new behaviour aligns with the existing behaviour of Packer### Changed - Speed improvements
Added ability to specify that items are pre-sorted when creating an ItemList from an array
ItemList from an arrayConstrainedItem is now deprecated. Use ConstrainedPlacementItem instead
ConstrainedPlacementItem as a more powerful version of ConstrainedItemConstrainedItem is now deprecated. Use ConstrainedPlacementItem insteadFixed divide by zero warning when attempting to pack an item with 0 depth
Fixed issue where internal sort consistency wasn't always correct
Added getVolume() helper method to PackedItem [Cosmologist]
getVolume() helper method to PackedItem [Cosmologist]Worked around an PHP recursion issue when comparing 2 Items.
Items.Fixed typos in documentation code samples
Tweaked composer configuration to make it easier to run the samples in the documentation
Optional 'Infallible' mode of packing to not throw an exception on error (e.g. item too large) but to continue packing the other items
Declare PackedBoxList as implementing Countable
PackedBoxList as implementing CountableIntroduced PackedItems which are a wrapper around Items with positional and dimensional information (x, y, z co-ordinates of corner closest to origin,
PackedItems which are a wrapper around Items with positional and dimensional information (x, y, z co-ordinates of corner closest to origin, width/length/depth as packed)PackedBox now contains a PackedItemList of PackedItems (rather than an ItemList of Items)ConstrainedItem->canBePackedInBox() now takes a PackedItemList of PackedItems (rather than an ItemList of Items)BoxList, ItemList, PackedBoxList have been altered to implement the Traversable interface rather than extend SplHeap directly so that any future changes to the internals will not need an API changeMaking the test suite compatible with PHP 8.0 has necessitated the removal of support for PHP 5.4 - 7.0 (see note below)
v2 of BoxPacker is in maintenance mode only, all users are encouraged to update to v3. This release has been made primarily to certify PHP 8 compatibility, unless an egregious bug is discovered (e.g. a physically impossible packing) this will probably be the last v2 release that includes any changes to core packing logic. (Any) further releases are intended to be limited to compatibility with future PHP versions.
Fixed situation where internal WorkingVolume could be passed into a constraint callback, rather than the calling application's own Box
WorkingVolume could be passed into a constraint callback, rather than the calling application's own BoxImproved efficiency in packing and weight distribution
@internal classes or made use of @internal methods you may be affected.Further optimisation when packing a large number of items
Optimisation when packing a large number of identical items
Improved efficiency in packing and weight distribution
ItemList passed to VolumePacker's constructor is now cloned before usage, leaving the passed-in object unaffected. Previously this was used as a working dataset. The new behaviour aligns with the existing behaviour of Packer### Changed - Speed enhancements
### Changed - Speed enhancements
ConstrainedItem is now deprecated. Use ConstrainedPlacementItem instead
ConstrainedPlacementItem as a more powerful version of ConstrainedItemConstrainedItem is now deprecated. Use ConstrainedPlacementItem insteadBackported positional data support from v3 via new getPackedItems() method on PackedBox
getPackedItems() method on PackedBoxFixed issue where internal sort consistency wasn't always correct
Improved item orientation selection for better packing
Worked around an PHP recursion issue when comparing 2 Items.
Items.Tweaked composer configuration to make it easier to run the samples in the documentation
Improved box selection for certain cases
Improved item orientation selection for better packing
Previously 2 distinct item types could be mixed when sorting items for packing if they had identical physical dimensions. Now if all dimensions are id
Used/remaining space calculations were sometimes offset by 90 degrees leading to confusing numbers
Significant reworking of core packing logic to clarify concepts used
getUsed[Width|Length|Depth]() could sometimes return an incorrect valueIn some cases, complex user-added constraints via BoxPacker\ConstrainedItem were not being obeyed
BoxPacker\ConstrainedItem were not being obeyedPackedBox->getUsedDepth() could incorrectly return a value of 0 in some situations
PackedBox->getUsedDepth() could incorrectly return a value of 0 in some situationsAdd callback system for more complex constraints e.g. max number of hazardous items in a box. To take advantage of the additional flexibility, impleme
Added getItem() to ItemTooLargeException to make it programmatically possible determine what the affected item is
getItem() to ItemTooLargeException to make it programmatically possible determine what the affected item isThe previous limitation that all items were always packed flat has been removed
ItemTooLargeException exception is now thrown when an item cannot fit inside any boxes rather than a generic \RuntimeExceptionAdded getUsed[Width|Length|Depth]() on PackedBoxes to allow for better visibility into space utilisation
getUsed[Width|Length|Depth]() on PackedBoxes to allow for better visibility into space utilisationYour coding agent can read these notes before it upgrades. Set up the MCP server →