I’m trying to retrieve a list of catalog items using PHP. I am able to send a request and receive a response. However, when I try to loop through the array of returned CatalogItems from the getObjects() method, they do not seem to respond as I expect.
use Square\SquareClient;
use Square\Environments;
use Square\Catalog\Requests\SearchCatalogObjectsRequest;
use Square\Types\CatalogObjectType;
use Square\Types\CatalogObjectItem;
use Square\Types\CatalogObject;
use Square\Types\CatalogItem;
use Square\Legacy\Models;
$client = new SquareClient(
token: 'XXX',
options: [
'baseUrl' => Environments::Sandbox->value,
],
);
$reply = $client->catalog->search(
new SearchCatalogObjectsRequest([
'includeRelatedObjects' => true,
'objectTypes' => [
CatalogObjectType::Item->value,
CatalogObjectType::Image->value,
CatalogObjectType::Category->value,
],
]),
);
$items = $reply->getObjects();
print_r( $items );
print_r( $items[0]->getType() );
print_r( get_class( $items[0] ) );
print_r( $items[0]->getId() );
The results are:
array:3 [▼
0 => Square\Types\CatalogObject {#2882 ▶}
1 => Square\Types\CatalogObject {#2907 ▶}
2 => Square\Types\CatalogObject {#2881 ▶}
]
ITEM
Square\Types\CatalogObject
Fatal error: Uncaught Error: Call to undefined method Square\Types\CatalogObject::getId()
I’m not sure why getType() works but getId() does not. Actually getType() seems to be the only method that works. Any help how I can interact with the returned objects?
I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:
Additional Documentation
Catalog API
Categorize Catalog Items
Call the SearchCatalogObjects Endpoint
If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.
The issue you’re encountering is likely due to the fact that the CatalogObject class in the Square PHP SDK does not have a getId() method. Instead, you should use the getId() method directly on the CatalogObject instance, as it is a property of the CatalogObject class.
Here’s how you can interact with the returned objects:
-
Accessing the ID: Use the id property directly, as CatalogObject instances have public properties rather than getter methods for some attributes.
-
Accessing Other Properties: Similarly, for other properties like version, isDeleted, etc., you should access them directly as properties.
Here’s an example of how you can modify your code to access the id and other properties:
foreach ($items as $item) {
echo "ID: " . $item->id . "\n";
echo "Type: " . $item->getType() . "\n";
// Access other properties as needed
}
By accessing the properties directly, you should be able to retrieve the information you need from the CatalogObject instances.
This answer was reviewed by @Bryan-Square.
Thanks Bryan.
I’m not actually after the ID or Type, per se. I actually want the name, price, image, description, etc. But I cannot seem to retrieve anything but the Type from the returned object.
I added your foreach loop and this was returned:
Warning: Undefined property: Square\Types\CatalogObject::$id [filepath] on line [line no]
ID: Type: ITEM
Warning: Undefined property: Square\Types\CatalogObject::$id [filepath] on line [line no]
ID: Type: ITEM
Warning: Undefined property: Square\Types\CatalogObject::$id [filepath] on line [line no]
ID: Type: IMAGE
I’ve been looking through the source code of the CatalogObject and CatalogObjectItem class. All the properties are private, which makes sense. But none of the methods seem to work. Do I need to have some other use statements to include the correct classes? I tried to include all the ones referenced in the objects returned with the first print_r( $items ) call.
The whole object looks like this, fwiw.
Square\Types\CatalogObject Object
(
[__additionalProperties:Square\Core\Json\JsonSerializableType:private] => Array
(
)
[type:Square\Types\CatalogObject:private] => ITEM
[value:Square\Types\CatalogObject:private] => Square\Types\CatalogObjectItem Object
(
[__additionalProperties:Square\Core\Json\JsonSerializableType:private] => Array
(
[type] => ITEM
[created_at] => 2025-09-30T17:19:47.034Z
)
[itemData:Square\Types\CatalogObjectItem:private] => Square\Types\CatalogItem Object
(
[__additionalProperties:Square\Core\Json\JsonSerializableType:private] => Array
(
)
[name:Square\Types\CatalogItem:private] => TEST NAME
[description:Square\Types\CatalogItem:private] => Lorem ipsum.
[abbreviation:Square\Types\CatalogItem:private] =>
[labelColor:Square\Types\CatalogItem:private] =>
[isTaxable:Square\Types\CatalogItem:private] => 1
[categoryId:Square\Types\CatalogItem:private] =>
[taxIds:Square\Types\CatalogItem:private] =>
[modifierListInfo:Square\Types\CatalogItem:private] =>
[variations:Square\Types\CatalogItem:private] => Array
(
[0] => Square\Types\CatalogObject Object
(
[__additionalProperties:Square\Core\Json\JsonSerializableType:private] => Array
(
)
[type:Square\Types\CatalogObject:private] => ITEM_VARIATION
[value:Square\Types\CatalogObject:private] => Square\Types\CatalogObjectItemVariation Object
(
[__additionalProperties:Square\Core\Json\JsonSerializableType:private] => Array
(
[type] => ITEM_VARIATION
[created_at] => 2025-09-30T17:19:47.034Z
)
[itemVariationData:Square\Types\CatalogObjectItemVariation:private] => Square\Types\CatalogItemVariation Object
(
[__additionalProperties:Square\Core\Json\JsonSerializableType:private] => Array
(
)
[itemId:Square\Types\CatalogItemVariation:private] => HY2JWJXYBSNRGIQAV4VUU4E5
[name:Square\Types\CatalogItemVariation:private] => Regular
[sku:Square\Types\CatalogItemVariation:private] =>
[upc:Square\Types\CatalogItemVariation:private] =>
[ordinal:Square\Types\CatalogItemVariation:private] => 1
[pricingType:Square\Types\CatalogItemVariation:private] => VARIABLE_PRICING
[priceMoney:Square\Types\CatalogItemVariation:private] =>
[locationOverrides:Square\Types\CatalogItemVariation:private] => Array
(
[0] => Square\Types\ItemVariationLocationOverrides Object
(
[__additionalProperties:Square\Core\Json\JsonSerializableType:private] => Array
(
)
[locationId:Square\Types\ItemVariationLocationOverrides:private] => LNK3YBE57GVAR
[priceMoney:Square\Types\ItemVariationLocationOverrides:private] =>
[pricingType:Square\Types\ItemVariationLocationOverrides:private] =>
[trackInventory:Square\Types\ItemVariationLocationOverrides:private] =>
[inventoryAlertType:Square\Types\ItemVariationLocationOverrides:private] =>
[inventoryAlertThreshold:Square\Types\ItemVariationLocationOverrides:private] =>
[soldOut:Square\Types\ItemVariationLocationOverrides:private] =>
[soldOutValidUntil:Square\Types\ItemVariationLocationOverrides:private] =>
)
)
[trackInventory:Square\Types\CatalogItemVariation:private] =>
[inventoryAlertType:Square\Types\CatalogItemVariation:private] =>
[inventoryAlertThreshold:Square\Types\CatalogItemVariation:private] =>
[userData:Square\Types\CatalogItemVariation:private] =>
[serviceDuration:Square\Types\CatalogItemVariation:private] =>
[availableForBooking:Square\Types\CatalogItemVariation:private] =>
[itemOptionValues:Square\Types\CatalogItemVariation:private] =>
[measurementUnitId:Square\Types\CatalogItemVariation:private] =>
[sellable:Square\Types\CatalogItemVariation:private] => 1
[stockable:Square\Types\CatalogItemVariation:private] => 1
[imageIds:Square\Types\CatalogItemVariation:private] =>
[teamMemberIds:Square\Types\CatalogItemVariation:private] =>
[stockableConversion:Square\Types\CatalogItemVariation:private] =>
)
[id:Square\Types\CatalogObjectItemVariation:private] => AT7ZHPKTLNQXWIKXWR7ZKEFO
[updatedAt:Square\Types\CatalogObjectItemVariation:private] => 2025-09-30T17:19:47.483Z
[version:Square\Types\CatalogObjectItemVariation:private] => 1759252787483
[isDeleted:Square\Types\CatalogObjectItemVariation:private] =>
[customAttributeValues:Square\Types\CatalogObjectItemVariation:private] =>
[catalogV1Ids:Square\Types\CatalogObjectItemVariation:private] =>
[presentAtAllLocations:Square\Types\CatalogObjectItemVariation:private] => 1
[presentAtLocationIds:Square\Types\CatalogObjectItemVariation:private] =>
[absentAtLocationIds:Square\Types\CatalogObjectItemVariation:private] =>
[imageId:Square\Types\CatalogObjectItemVariation:private] =>
)
)
)
[productType:Square\Types\CatalogItem:private] => FOOD_AND_BEV
[skipModifierScreen:Square\Types\CatalogItem:private] =>
[itemOptions:Square\Types\CatalogItem:private] =>
[ecomUri:Square\Types\CatalogItem:private] =>
[ecomImageUris:Square\Types\CatalogItem:private] =>
[imageIds:Square\Types\CatalogItem:private] => Array
(
[0] => 6ZXNBMIVRFMV74THBJDY46RW
)
[sortName:Square\Types\CatalogItem:private] =>
[categories:Square\Types\CatalogItem:private] =>
[descriptionHtml:Square\Types\CatalogItem:private] =>
Lorem ipsum.
[descriptionPlaintext:Square\Types\CatalogItem:private] => Lorem ipsum.
[channels:Square\Types\CatalogItem:private] =>
[isArchived:Square\Types\CatalogItem:private] =>
[ecomSeoData:Square\Types\CatalogItem:private] =>
[foodAndBeverageDetails:Square\Types\CatalogItem:private] =>
[reportingCategory:Square\Types\CatalogItem:private] =>
[isAlcoholic:Square\Types\CatalogItem:private] =>
)
[id:Square\Types\CatalogObjectItem:private] => HY2JWJXYBSNRGIQAV4VUU4E5
[updatedAt:Square\Types\CatalogObjectItem:private] => 2025-09-30T17:19:47.483Z
[version:Square\Types\CatalogObjectItem:private] => 1759252787483
[isDeleted:Square\Types\CatalogObjectItem:private] =>
[customAttributeValues:Square\Types\CatalogObjectItem:private] =>
[catalogV1Ids:Square\Types\CatalogObjectItem:private] =>
[presentAtAllLocations:Square\Types\CatalogObjectItem:private] => 1
[presentAtLocationIds:Square\Types\CatalogObjectItem:private] =>
[absentAtLocationIds:Square\Types\CatalogObjectItem:private] =>
[imageId:Square\Types\CatalogObjectItem:private] =>
)
)
Thanks.
If you try this does it give you what your looking for:
<?php
/**
* Square Catalog API Example - Fixed Version Based on Actual SDK
*
* This example uses the correct Square PHP SDK structure and imports
* based on the official documentation from GitHub.
*/
require_once 'vendor/autoload.php';
use Square\SquareClient;
use Square\Environments;
use Square\Catalog\Requests\SearchCatalogObjectsRequest;
// Initialize the Square client using the correct constructor pattern
$client = new SquareClient(
'ACCESS_TOKEN', // token
null, // version (use default)
[
'baseUrl' => Environments::Production->value // Use Environments::Production for live
]
);
try {
// Make the API call using the correct method structure
$request = new SearchCatalogObjectsRequest([
'includeRelatedObjects' => true,
'objectTypes' => ['ITEM', 'IMAGE', 'CATEGORY']
]);
$apiResponse = $client->catalog->search($request);
// Check for errors first
$errors = $apiResponse->getErrors();
if ($errors && count($errors) > 0) {
echo "API Error:\n";
foreach ($errors as $error) {
echo "- " . $error->getCategory() . ": " . $error->getDetail() . "\n";
}
} else {
$objects = $apiResponse->getObjects();
if ($objects && count($objects) > 0) {
echo "Found " . count($objects) . " objects\n\n";
// Debug the first object to see available methods
echo "=== DEBUGGING FIRST OBJECT ===\n";
$firstObject = $objects[0];
echo "Class: " . get_class($firstObject) . "\n";
echo "Available getter methods:\n";
$reflection = new ReflectionClass($firstObject);
$methods = $reflection->getMethods(ReflectionMethod::IS_PUBLIC);
foreach ($methods as $method) {
if (strpos($method->getName(), 'get') === 0) {
echo " - " . $method->getName() . "\n";
}
}
echo "\n=== TESTING METHODS ===\n";
// Test the methods that actually exist
try {
echo "Type: " . ($firstObject->getType() ?? 'NULL') . "\n";
} catch (Error $e) {
echo "getType() failed: " . $e->getMessage() . "\n";
}
try {
$value = $firstObject->getValue();
echo "Value type: " . gettype($value) . "\n";
echo "Value class: " . (is_object($value) ? get_class($value) : 'Not an object') . "\n";
if (is_object($value)) {
echo "Available methods on Value object:\n";
$valueReflection = new ReflectionClass($value);
$valueMethods = $valueReflection->getMethods(ReflectionMethod::IS_PUBLIC);
foreach ($valueMethods as $method) {
if (strpos($method->getName(), 'get') === 0) {
echo " - " . $method->getName() . "\n";
}
}
// Test common methods on the value object
if (method_exists($value, 'getId')) {
echo " ID from getValue(): " . ($value->getId() ?? 'NULL') . "\n";
}
if (method_exists($value, 'getVersion')) {
echo " Version from getValue(): " . ($value->getVersion() ?? 'NULL') . "\n";
}
if (method_exists($value, 'getUpdatedAt')) {
echo " Updated At from getValue(): " . ($value->getUpdatedAt() ?? 'NULL') . "\n";
}
}
} catch (Error $e) {
echo "getValue() failed: " . $e->getMessage() . "\n";
}
try {
$additionalProps = $firstObject->getAdditionalProperties();
echo "Additional Properties: " . json_encode($additionalProps) . "\n";
} catch (Error $e) {
echo "getAdditionalProperties() failed: " . $e->getMessage() . "\n";
}
// Try some other common methods that might exist
$commonMethods = [
'getUid', 'getObjectId', 'getCatalogObjectId', 'getIdentifier',
'getPresentAtAllLocations', 'getPresentAtLocationIds', 'getAbsentAtLocationIds'
];
foreach ($commonMethods as $methodName) {
if (method_exists($firstObject, $methodName)) {
try {
$value = $firstObject->$methodName();
echo "$methodName: " . (is_array($value) ? json_encode($value) : ($value ?? 'NULL')) . "\n";
} catch (Error $e) {
echo "$methodName failed: " . $e->getMessage() . "\n";
}
} else {
echo "$methodName: Method does not exist\n";
}
}
echo "\n=== PROCESSING ALL OBJECTS ===\n";
// Process all objects with the correct methods
foreach ($objects as $index => $catalogObject) {
echo "\nObject #" . ($index + 1) . ":\n";
// Get the type (this works)
echo " Type: " . ($catalogObject->getType() ?? 'N/A') . "\n";
// Get the value object which contains the actual data
$value = $catalogObject->getValue();
if ($value && is_object($value)) {
echo " Value Class: " . get_class($value) . "\n";
// Try to get ID from the value object
if (method_exists($value, 'getId')) {
echo " ID: " . ($value->getId() ?? 'N/A') . "\n";
}
// Try to get version from the value object
if (method_exists($value, 'getVersion')) {
echo " Version: " . ($value->getVersion() ?? 'N/A') . "\n";
}
// Try to get updated at from the value object
if (method_exists($value, 'getUpdatedAt')) {
echo " Updated At: " . ($value->getUpdatedAt() ?? 'N/A') . "\n";
}
}
// Handle specific object types using getValue()
$objectType = $catalogObject->getType();
switch ($objectType) {
case 'ITEM':
if ($value && method_exists($value, 'getItemData')) {
$itemData = $value->getItemData();
if ($itemData) {
echo " Item Name: " . ($itemData->getName() ?? 'Unnamed') . "\n";
echo " Description: " . ($itemData->getDescription() ?? 'No description') . "\n";
// Show variations if they exist
if (method_exists($itemData, 'getVariations')) {
$variations = $itemData->getVariations();
if ($variations && count($variations) > 0) {
echo " Variations: " . count($variations) . "\n";
foreach ($variations as $varIndex => $variation) {
$variationValue = null;
if (method_exists($variation, 'getValue')) {
$variationValue = $variation->getValue();
} else {
$variationValue = $variation;
}
if ($variationValue && method_exists($variationValue, 'getId')) {
echo " Variation " . ($varIndex + 1) . " ID: " . ($variationValue->getId() ?? 'N/A') . "\n";
}
if ($variationValue && method_exists($variationValue, 'getItemVariationData')) {
$variationData = $variationValue->getItemVariationData();
if ($variationData) {
echo " Name: " . ($variationData->getName() ?? 'Default') . "\n";
if (method_exists($variationData, 'getPriceMoney')) {
$priceMoney = $variationData->getPriceMoney();
if ($priceMoney) {
$amount = $priceMoney->getAmount();
$currency = $priceMoney->getCurrency();
$displayAmount = $amount ? ($amount / 100) : 0;
echo " Price: $" . number_format($displayAmount, 2) . " " . $currency . "\n";
}
}
}
}
}
}
}
}
}
break;
case 'CATEGORY':
if ($value && method_exists($value, 'getCategoryData')) {
$categoryData = $value->getCategoryData();
if ($categoryData) {
echo " Category Name: " . ($categoryData->getName() ?? 'Unnamed Category') . "\n";
}
}
break;
case 'IMAGE':
if ($value && method_exists($value, 'getImageData')) {
$imageData = $value->getImageData();
if ($imageData) {
echo " Image Name: " . ($imageData->getName() ?? 'Unnamed Image') . "\n";
echo " Image URL: " . ($imageData->getUrl() ?? 'No URL') . "\n";
}
}
break;
default:
echo " Unknown object type: $objectType\n";
}
}
} else {
echo "No catalog objects found.\n";
}
}
} catch (Exception $e) {
echo "Exception: " . $e->getMessage() . "\n";
echo "File: " . $e->getFile() . " Line: " . $e->getLine() . "\n";
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
}
?>

Bryan – I sincerely appreciate the thorough help!
Here’s what your snippet returned:
Found 3 objects
=== DEBUGGING FIRST OBJECT ===
Class: Square\Types\CatalogObject
Available getter methods:
- getType
- getValue
- getAdditionalProperties
=== TESTING METHODS ===
Type: ITEM
Value type: object
Value class: Square\Types\CatalogObjectItem
Available methods on Value object:
- getItemData
- getAdditionalProperties
- getId
- getUpdatedAt
- getVersion
- getIsDeleted
- getCustomAttributeValues
- getCatalogV1Ids
- getPresentAtAllLocations
- getPresentAtLocationIds
- getAbsentAtLocationIds
- getImageId
ID from getValue(): FQKE4HBJR3RE4FF4FZFNQP2Q
Version from getValue(): 1759252681972
Updated At from getValue(): 2025-09-30T17:18:01.972Z
Additional Properties: []
getUid: Method does not exist
getObjectId: Method does not exist
getCatalogObjectId: Method does not exist
getIdentifier: Method does not exist
getPresentAtAllLocations: Method does not exist
getPresentAtLocationIds: Method does not exist
getAbsentAtLocationIds: Method does not exist
=== PROCESSING ALL OBJECTS ===
Object #1:
Type: ITEM
Value Class: Square\Types\CatalogObjectItem
ID: FQKE4HBJR3RE4FF4FZFNQP2Q
Version: 1759252681972
Updated At: 2025-09-30T17:18:01.972Z
Item Name: Premient
Description: No description
Variations: 1
Variation 1 ID: 5Q4GJZIDU4DWZ52CRTLOOEHL
Name: Regular
Price: $16.00 USD
Object #2:
Type: ITEM
Value Class: Square\Types\CatalogObjectItem
ID: HY2JWJXYBSNRGIQAV4VUU4E5
Version: 1759252787483
Updated At: 2025-09-30T17:19:47.483Z
Item Name: Klinker
Description: Lorem ipsum german pilsener.
Variations: 1
Variation 1 ID: AT7ZHPKTLNQXWIKXWR7ZKEFO
Name: Regular
Object #3:
Type: IMAGE
Value Class: Square\Types\CatalogObjectImage
ID: 6ZXNBMIVRFMV74THBJDY46RW
Version: 1759252750927
Updated At: 2025-09-30T17:19:10.927Z
Image Name: just-testing.jpg
Image URL: https://items-images-sandbox.s3.us-west-2.amazonaws.com/files/cbcbcb4f0cb45a8fe679bd84bc5159821f
So, I think my issue before was not drilling down to the $catalogObject→getValue(), then trying the getName() methods on the returned value objects.
Interestingly, the Testing Methods section of your code said those methods don’t exist!
Additional Properties: []
getUid: Method does not exist
getObjectId: Method does not exist
getCatalogObjectId: Method does not exist
getIdentifier: Method does not exist
getPresentAtAllLocations: Method does not exist
getPresentAtLocationIds: Method does not exist
getAbsentAtLocationIds: Method does not exist
While working on it more myself, I did find that $catlogObject→jsonSerialize() worked, and I was able to parse through the returned array easily enough, though using the object methods will be better.
SO, for future forum readers, I would say the answer to my original question is to loop through the array of CatalogObjects running $value = $CatalogObject→getValue() before then using the other methods on $value like $value→getName() or $value→getDescription().
Again, 100x thank you.
Glad to hear that you got it working the way you want. 