dvdoug/boxpacker
An implementation of the 3D (actually 4D) bin packing/knapsack problem (aka creating parcels by putting items into boxes)
4.3.0
3.0M downloads/mo
#3178 most downloaded on Packagist
dvdoug/BoxPacker
What this package is like to depend on
Last release 14 days ago
09 Aug 2026
Ships fairly regularly
a new release about every 5 months
Nearly every release is documented
notes for 93 of 93 stable releases
Nothing withdrawn
no release was ever pulled
13 years old
93 releases · first in 2013
2 releases in the last 12 months
see the full history below
Release timeline
93 releases · Jul 2013 to Aug 2026Releases
latest 60 of 93-
4.3.009 Aug 2026Release notes
Open source →Changed
- Improved efficiency in packing
Fixed
- In some rare cases
WeightRedistributorwould silently drop items - Sort linked items to give them the best chance of being packed together, to prevent no boxes being found due to the items being out of order.
Release notes
Open source →Changed
- Improved efficiency in packing
Fixed
- In some rare cases
WeightRedistributorwould silently drop items - Sort linked items to give them the best chance of being packed together, to prevent no boxes being found due to the items being out of order.
-
4.2.005 Jul 2026Release notes
Open source →Added
- A mechanism to allow forcing certain items to be packed together [RubenKluft]
Release notes
Open source →Added
- A mechanism to allow forcing certain items to be packed together [RubenKluft]
-
4.1.121 Jul 2025Release notes
Open source →Fixed
- In some cases the maximum weight of a box was not respected
- Sometimes boxes were not ordered canonically
- Visualisation links did not encode the query params
Release notes
Open source →Fixed
- In some cases the maximum weight of a box was not respected
- Sometimes boxes were not ordered canonically
- Visualisation links did not encode the query params
-
4.1.006 Feb 2025Release notes
Open source →Added
- A mechanism to allow a proactive timeout on v. large packings rather than run to completion
Release notes
Open source →Added
- A mechanism to allow a proactive timeout on v. large packings rather than run to completion
-
4.0.101 Apr 2024 -
4.0.004 Dec 2023Release notes
Open source →Added
- Added new enumeration
Rotationwith valuesNever,KeepFlatandBestFit - Added new
getAllowedRotation()method to theIteminterface to replacegetKeepFlat(). This should return
one of the newRotationenum values - Added new
generateVisualisationURL()method toPackedBoxandPackedBoxList. This will generate a custom URL for
a visualisation you can access via the BoxPacker website - Added new
packAllPermutations()method toPackerto calculate all possible box combinations - Added
throwOnUnpackableItem()toPackerto control if an exception is thrown (or not) if an unpackable item is
found (defaults to true, consistent with previous behaviour) - Added
getUnpackedItems()toPackerto retrieve the list of items that could not be packed (only applicable if
exceptions are disabled) PackedBoxnow has readonly public properties->boxand->itemPackedItemnow has readonly public properties->item,->x,->y,->z,->width,->length,->depth
Changed
- Minimum PHP version is now 8.2
- Exceptions are now in the
DVDoug\BoxPacker\Exceptionnamespace (previouslyDVDoug\BoxPacker) - The signature of the
->canBePackedmethod on theConstrainedPlacementIteminterface has been changed to replace the
first two arguments(Box $box,PackedItemList $alreadyPackedItems) withPackedBox $packedBox. This allows
callbacks to make use of the helper methods provided onPackedBox. Access to the box and items can be done via
$packedBox->boxand$packedBox->items NoBoxesAvailableExceptionnow has a->getAffectedItems()method instead of->getItem(). This should allow
improved handling of the exception inside calling applications when multiple items cannot be packed
Removed
- Removed
getBox()andgetItems()fromPackedBox. Use the new public properties instead - Removed
->getItem(),->getX(),->getY(),->getZ(),->getWidth(),->getLength()and->getDepth()
fromPackedItem. Use the new public properties instead - Removed deprecated
ConstrainedItem. You should useConstrainedPlacementItemas a replacement - Removed
getKeepFlat()from theIteminterface - Removed
InfalliblePacker. You can now get the same behaviour by calling->throwOnUnpackableItem(false)and
->getUnpackedItems()on the mainPackerclass
Release notes
Open source →Added
- Added new enumeration
Rotationwith valuesNever,KeepFlatandBestFit - Added new
getAllowedRotation()method to theIteminterface to replacegetKeepFlat(). This should return one of the newRotationenum values - Added new
generateVisualisationURL()method toPackedBoxandPackedBoxList. This will generate a custom URL for a visualisation you can access via the BoxPacker website - Added new
packAllPermutations()method toPackerto calculate all possible box combinations - Added
throwOnUnpackableItem()toPackerto control if an exception is thrown (or not) if an unpackable item is found (defaults to true, consistent with previous behaviour) - Added
getUnpackedItems()toPackerto retrieve the list of items that could not be packed (only applicable if exceptions are disabled) PackedBoxnow has readonly public properties->boxand->itemPackedItemnow has readonly public properties->item,->x,->y,->z,->width,->length,->depth
Changed
- Minimum PHP version is now 8.2
- Exceptions are now in the
DVDoug\BoxPacker\Exceptionnamespace (previouslyDVDoug\BoxPacker) - The signature of the
->canBePackedmethod on theConstrainedPlacementIteminterface has been changed to replace the first two arguments(Box $box,PackedItemList $alreadyPackedItems) withPackedBox $packedBox. This allows callbacks to make use of the helper methods provided onPackedBox. Access to the box and items can be done via$packedBox->boxand$packedBox->items NoBoxesAvailableExceptionnow has a->getAffectedItems()method instead of->getItem(). This should allow improved handling of the exception inside calling applications when multiple items cannot be packed
Removed
- Removed
getBox()andgetItems()fromPackedBox. Use the new public properties instead - Removed
->getItem(),->getX(),->getY(),->getZ(),->getWidth(),->getLength()and->getDepth()fromPackedItem. Use the new public properties instead - Removed deprecated
ConstrainedItem. You should useConstrainedPlacementItemas a replacement - Removed
getKeepFlat()from theIteminterface - Removed
InfalliblePacker. You can now get the same behaviour by calling->throwOnUnpackableItem(false)and->getUnpackedItems()on the mainPackerclass
- Added new enumeration
-
3.12.102 Dec 2023Release notes
Open source →Fixed
- Restored ability to copy/paste the samples from the docs into a non-dev installation
Release notes
Open source →Fixed
- Restored ability to copy/paste the samples from the docs into a non-dev installation
-
3.12.029 Jul 2023Release notes
Open source →Changed
- Improved efficiency in packing
Removed
- Support for PHP 7.1, 7.2 and 7.3
Release notes
Open source →Changed
- Improved efficiency in packing
Removed
- Support for PHP 7.1, 7.2 and 7.3
-
3.11.004 Feb 2023Release notes
Open source →Changed
- Calling
json_encode()on aPackedBoxorPackedItemnow additionally serialises the entire underlying
Box/Itemwhere those objects also implementJsonSerializable. Previously the serialisation only included the
key values from theBox/Iteminterfaces themselves.
Release notes
Open source →Changed
- Calling
json_encode()on aPackedBoxorPackedItemnow additionally serialises the entire underlyingBox/Itemwhere those objects also implementJsonSerializable. Previously the serialisation only included the key values from theBox/Iteminterfaces themselves.
- Calling
-
3.10.010 Sep 2022Release notes
Open source →Added
- Added
ItemSorter,BoxSorterandPackedBoxSorterto allow calling applications to have better control over
sorting decisions - Added
beStrictAboutItemOrdering()toPackerandVolumePacker
Release notes
Open source →Added
- Added
ItemSorter,BoxSorterandPackedBoxSorterto allow calling applications to have better control over sorting decisions - Added
beStrictAboutItemOrdering()toPackerandVolumePacker
- Added
-
3.9.421 Oct 2021 -
3.9.326 Sep 2021 -
3.9.204 Jul 2021Release notes
Open source →Added
- Optional second parameter
$qtytoItemList->insert()
Fixed
- Fixed issue where available width for an item could be miscalculated
Changed
- Improved memory usage
- Optional second parameter
-
3.9.105 May 2021Release notes
Open source →Fixed
- Fixed issue where available width for an item could be miscalculated at the far end of a box
Changed
- Improved efficiency in packing in the vertical direction
-
3.9.014 Mar 2021Release notes
Open source →Added
- Added
packAcrossWidthOnly()toVolumePackerfor scenarios where the container will be side-loaded rather than top-loaded (e.g. truck loading) - Added
getWeight()helper method toPackedItemList - Experimental visualisation tool has been added to the repo. All aspects of the tool are subject to change.
Changed
- Improved efficiency in packing
- Added
-
3.8.026 Jan 2021Release notes
Open source →Added
- Added
fromArray()helper method toBoxListto make bulk add easier [bram123]
- Added
-
3.7.001 Jan 2021 -
3.6.228 Sep 2020 -
3.6.111 Jun 2020Release notes
Open source →Fixed
- Fixed situation where internal
WorkingVolumecould be passed into a constraint callback, rather than the calling application's ownBox - Fixed issue where the list of previously packed items passed into a constraint callback was not correct
- Fixed situation where internal
-
3.6.026 Apr 2020Release notes
Open source →Changed
- Improved efficiency in packing and weight distribution
- Major internal refactoring. The public-facing API did not change in any incompatible ways, but if you extended any of the
@internalclasses or made use of@internalmethods you may be affected. - Bail out earlier in the packing process where an item doesn't fit [colinmollenhour]
Fixed
- Fixed potential issue where internal sort consistency wasn't always correct
- Fixed potential issue where custom constraints might not be fully respected
- Avoid divide by zero error when a box is specified to have a depth of 0mm (e.g. 2D packing)
- Better docblocks [colinmollenhour]
-
3.5.202 Feb 2020 -
3.5.130 Jan 2020 -
3.5.026 Jan 2020Release notes
Open source →Added
- Added a new interface
LimitedSupplyBox extends Boxfor situations where there are restrictions on the number of a box type available for packingItems into. The interface contains 1 additional methodgetQuantityAvailable(). - Added new exception
NoBoxesAvailableExceptionwhich 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 existingItemTooLargeExceptionwhich 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 fromNoBoxesAvailableExceptionas a special case
Changed
- Improved efficiency in packing and weight distribution
- The
ItemListpassed toVolumePacker'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 ofPacker
Fixed
- Fixed issue where internal sort consistency wasn't always correct
- Some debug-level logging wasn't logging correctly
- Added a new interface
-
3.4.121 Dec 2019 -
3.4.009 Sep 2019Release notes
Open source →Added
- Added ability to specify that items are pre-sorted when creating an
ItemListfrom an array
Changed
- Significant speed improvements when dealing with a large number of items
- Added ability to specify that items are pre-sorted when creating an
-
3.3.014 Jul 2019Release notes
Open source →Added
- Added
ConstrainedPlacementItemas a more powerful version ofConstrainedItem
Changed
- Improved box selection for certain cases
- Speed improvements
- Increased detail in debug-level logging
Deprecated
ConstrainedItemis now deprecated. UseConstrainedPlacementIteminstead
- Added
-
3.2.220 Nov 2018Release notes
Open source →Fixed
- Fixed divide by zero warning when attempting to pack an item with 0 depth
-
3.2.113 Nov 2018 -
3.2.012 Nov 2018Release notes
Open source →Added
- Added
getVolume()helper method toPackedItem[Cosmologist]
Changed
- Improved item orientation selection for better packing
- Minor refactorings for code clarity
- Added
-
3.1.315 Jun 2018 -
3.1.213 Jun 2018 -
3.1.103 Jun 2018Release notes
Open source →Changed
- Tweaked composer configuration to make it easier to run the samples in the documentation
- Minor speed improvements
-
3.1.019 Feb 2018Release notes
Open source →Added
- Optional 'Infallible' mode of packing to not throw an exception on error (e.g. item too large) but to continue packing the other items
Changed
- Improved stability algorithm
- Improved box selection for certain cases
- Some internal refactoring
-
3.0.101 Jan 2018Release notes
Open source →Added
- Declare
PackedBoxListas implementingCountable
Changed
- Improved item orientation selection for better packing
- Declare
-
3.0.023 Oct 2017Release notes
Open source →Added
- Introduced
PackedItems which are a wrapper aroundItems with positional and dimensional information (x, y, z co-ordinates of corner closest to origin, width/length/depth as packed) - Added method to set threshold at which weight redistribution is disabled
Changed
PackedBoxnow contains aPackedItemListofPackedItems (rather than anItemListofItems)ConstrainedItem->canBePackedInBox()now takes aPackedItemListofPackedItems (rather than anItemListofItems)BoxList,ItemList,PackedBoxListhave been altered to implement theTraversableinterface rather than extendSplHeapdirectly so that any future changes to the internals will not need an API change- Minimum PHP version is now 7.1
Removed
- HHVM support now that project has a stated goal of no longer targeting PHP7 compatibility
- Introduced
-
2.7.228 Sep 2020Release notes
Open source →Added
- Support for PHP 8.0
Removed
- Making 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.
-
2.7.111 Jun 2020Release notes
Open source →Fixed
- Fixed situation where internal
WorkingVolumecould be passed into a constraint callback, rather than the calling application's ownBox - Fixed issue where the list of previously packed items passed into a constraint callback was not correct
- Fixed situation where internal
-
2.7.024 Apr 2020Release notes
Open source →Changed
- Improved efficiency in packing and weight distribution
- Major internal refactoring. The public-facing API did not change in any incompatible ways, but if you extended any of the
@internalclasses or made use of@internalmethods you may be affected. - Bail out earlier in the packing process where an item doesn't fit [colinmollenhour]
Fixed
- Fixed potential issue where custom constraints might not be fully respected
- Avoid divide by zero error when a box is specified to have a depth of 0mm (e.g. 2D packing)
-
2.6.502 Feb 2020 -
2.6.430 Jan 2020 -
2.6.326 Jan 2020Release notes
Open source →Changed
- Improved efficiency in packing and weight distribution
- The
ItemListpassed toVolumePacker'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 ofPacker
Fixed
- Fixed issue where internal sort consistency wasn't always correct
- Some debug-level logging wasn't logging correctly
-
2.6.221 Dec 2019 -
2.6.115 Sep 2019 -
2.6.014 Jul 2019Release notes
Open source →Added
- Added
ConstrainedPlacementItemas a more powerful version ofConstrainedItem
Changed
- Improved box selection for certain cases
- Speed improvements
- Increased detail in debug-level logging
Deprecated
ConstrainedItemis now deprecated. UseConstrainedPlacementIteminstead
- Added
-
2.5.020 Nov 2018Release notes
Open source →Added
- Backported positional data support from v3 via new
getPackedItems()method onPackedBox
Fixed
- Fixed divide by zero warning when attempting to pack an item with 0 depth
- Backported positional data support from v3 via new
-
2.4.813 Nov 2018 -
2.4.712 Nov 2018Release notes
Open source →Changed
- Improved item orientation selection for better packing
- Minor refactorings for code clarity
-
2.4.615 Jun 2018 -
2.4.503 Jun 2018Release notes
Open source →Changed
- Tweaked composer configuration to make it easier to run the samples in the documentation
-
2.4.425 Feb 2018Release notes
Open source →Changed
- Improved stability algorithm
- Improved box selection for certain cases
- Some internal refactoring
-
2.4.301 Jan 2018 -
2.4.223 Oct 2017Release notes
Open source →Changed
- Previously 2 distinct item types could be mixed when sorting items for packing if they had identical physical dimensions. Now if all dimensions are identical, items are sorted by description so that they are kept together
-
2.4.104 Sep 2017Release notes
Open source →Fixed
- Used/remaining space calculations were sometimes offset by 90 degrees leading to confusing numbers
-
2.4.013 Aug 2017Release notes
Open source →Changed
- Significant reworking of core packing logic to clarify concepts used
Fixed
- Fixed issue where
getUsed[Width|Length|Depth]()could sometimes return an incorrect value
-
2.3.206 Aug 2017Release notes
Open source →Changed
- In some cases, complex user-added constraints via
BoxPacker\ConstrainedItemwere not being obeyed - Test classes refactored to be autoloadable
- Some internal refactoring
- In some cases, complex user-added constraints via
-
2.3.115 Apr 2017Release notes
Open source →Changed
PackedBox->getUsedDepth()could incorrectly return a value of 0 in some situations
-
2.3.009 Apr 2017Release notes
Open source →Added
- Add callback system for more complex constraints e.g. max number of hazardous items in a box. To take advantage of the additional flexibility, implement BoxPacker\ConstrainedItem rather than BoxPacker\Item
Changed
- Some internal refactoring
-
2.2.112 Mar 2017Release notes
Open source →Added
- Added
getItem()toItemTooLargeExceptionto make it programmatically possible determine what the affected item is
- Added
-
2.2.006 Mar 2017Release notes
Open source →Added
- The previous limitation that all items were always packed flat has been removed
- A specific
ItemTooLargeExceptionexception is now thrown when an item cannot fit inside any boxes rather than a generic\RuntimeException
-
2.1.007 Jan 2017Release notes
Open source →Added
- Added
getUsed[Width|Length|Depth]()on PackedBoxes to allow for better visibility into space utilisation
Changed
- Equal distribution of weight is now turned off when the number of boxes becomes large as it provides very little to no benefit at that scale and is slow to calculate
- Various optimisations and internal refactorings
- Added