Install the Bundle
composer require alkhvalko/sphinxsearch-bundle
(Note: The README references iakumai/sphinxsearch-bundle, but the package is actually alkhvalko/sphinxsearch-bundle per composer.json.)
Register the Bundle
Add to config/bundles.php (Symfony 4+):
IAkumaI\SphinxsearchBundle\SphinxsearchBundle::class => ['all' => true],
Configure Sphinx Connection
Add to config/packages/sphinxsearch.yaml:
sphinxsearch:
searchd:
host: localhost
port: 9312
indexes:
your_index_name: "App\Entity\YourEntity"
First Search Query Inject the service in a controller:
use IAkumaI\SphinxsearchBundle\Search\Sphinxsearch;
public function searchAction(Request $request, Sphinxsearch $sphinx)
{
$results = $sphinx->search($request->query->get('q'), ['your_index_name']);
return $this->render('search/results.html.twig', ['results' => $results]);
}
Basic Search
Use search() for simple queries:
$results = $sphinx->search('query', ['index1', 'index2']);
Entity Conversion
Use searchEx() with configured indexes to auto-hydrate entities:
$results = $sphinx->searchEx('query', 'index_name');
// $results['matches'][id]['entity'] contains the Doctrine entity.
Filtering Apply filters before searching:
$sphinx->setFilter('category_id', 5); // Exact match
$sphinx->setFilterRange('price', 10, 100); // Range filter
$sphinx->setFilterBetweenDates('created_at', $startDate, $endDate);
Pagination with Pagerfanta
$adapter = new \IAkumaI\SphinxsearchBundle\Pagerfanta\Adapter\SphinxSearchAdapter(
$sphinx,
'query',
'index_name',
['max_results' => 1000]
);
$pager = new Pagerfanta($adapter);
Highlighting in Twig
{{ result.content|sphinx_highlight('index_name', 'query') }}
$sphinx->setBridge($this->get('iakumai.sphinxsearch.doctrine.bridge'));
sphinx.conf:
sql_attr_uint = entity_id
sql_attr_timestamp = updated_at
searchEx() with an array of index names for cross-index searches.Index Configuration Mismatch
indexes in config.yml match your sphinx.conf sources.sphinx.conf defines source Example, your config must reference the corresponding index name (e.g., index Example).Entity Hydration Requirements
searchEx(), your Sphinx index must include an index_name attribute if querying multiple indexes.sql_query in sphinx.conf:
sql_query = SELECT ..., 'index_name' as index_name FROM table
Date Filtering Quirks
setFilterBetweenDates() expects DateTime objects or timestamps. Invalid formats (e.g., d.m.Y) will fail silently.Pagerfanta Adapter Caveats
$sphinx->setBridge()) before using the adapter.max_results) must be set to avoid performance issues.Deprecated Methods
romainneutron/Sphinx-Search-API-PHP-Client. Some methods (e.g., BuildExcerpts) may behave differently than the newer sphinxsearch/sphinxapi package.netstat -tulnp | grep 9312) and verify host/port in config.setLimits(0, 100) to debug if results are being filtered out.getId() method and matches the Sphinx id attribute.Custom Search Logic
Override the default service class by configuring iakumai.sphinxsearch.search.class in config/packages/sphinxsearch.yaml:
sphinxsearch:
search:
class: App\Service\CustomSphinxSearch
Doctrine Bridge Extensions
Implement IAkumaI\SphinxsearchBundle\Doctrine\BridgeInterface for custom entity hydration:
class CustomBridge implements BridgeInterface {
public function hydrate(array $match, string $indexName) {
// Custom logic here
}
}
Twig Filters
Extend the sphinx_highlight filter by overriding the bundle’s Twig extension.
sql_range_step for large datasets to avoid timeouts.category_id) for faster queries.How can I help you explore Laravel packages today?