php/ PDF zoekmachine
Voor een vereniging ben ik opzoek naar een methode om de oude clubbladen digitaal doorzoekbaar te maken.
Er zijn ± 1500 "boekjes" waarvan het merendeel als OCR PDF bestanden zijn.
Is er een PHP/MySQL script/methode/techniek die het mogelijk maakt om de bezoeker naar woorden in de PDF files te zoeken en dan de PDF bestand met het betreffende zoekwoord te presenteren?
Zeg maar een eigen Google search ;-|
kan iemand mij in de goede richten sturen.
Er zijn ± 1500 "boekjes" waarvan het merendeel als OCR PDF bestanden zijn.
Is er een PHP/MySQL script/methode/techniek die het mogelijk maakt om de bezoeker naar woorden in de PDF files te zoeken en dan de PDF bestand met het betreffende zoekwoord te presenteren?
Zeg maar een eigen Google search ;-|
kan iemand mij in de goede richten sturen.
Nee, zoeken naar woorden met ocr wordt een lastige opgave met zo een groot aantal PDF'jes. Dus het zal in ieder geval geïndexeerd moeten worden tot tekstueel formaat. Daarvoor kan je 'pdftotext' gebruiken.
Dat kan je dan in een database opslaan en met MySQL Fulltext doorzoeken.
Als je echt een goed schaalbare zoekoptie zoekt, dan kan je kijken naar Apache Solr of Elasticsearch.
Onthoud wel dat je voor dit alles een eigen server nodig hebt.
Dat kan je dan in een database opslaan en met MySQL Fulltext doorzoeken.
Als je echt een goed schaalbare zoekoptie zoekt, dan kan je kijken naar Apache Solr of Elasticsearch.
Onthoud wel dat je voor dit alles een eigen server nodig hebt.
** quoteknip**
OKe bedankt voor de tip iK ga daar even naar kijken
Maar ik denk eigenlijk dat zo'n project te groot is voor de website van de vereniging. Misschien is het beter als ze contact opnemen met het gemeentearchief of het nationale archief, Die hebben al dergelijke systemen. Maar dan is de vraag vinden die het interessant :-|
OKe bedankt voor de tip iK ga daar even naar kijken
Maar ik denk eigenlijk dat zo'n project te groot is voor de website van de vereniging. Misschien is het beter als ze contact opnemen met het gemeentearchief of het nationale archief, Die hebben al dergelijke systemen. Maar dan is de vraag vinden die het interessant :-|
Gewijzigd op 26/01/2026 10:15:23 door - Ariën -
Op welke manier is het te groot? Zijn er te weinig handen en know-how beschikbaar om het realiseren? Of is er te weinig capaciteit voor de data?
Als je een eigen server kan draaien, dan is het natuurlijk een leuk projectje om het eens vorm te geven.
De stappen zijn van: PDF -> Text - > MySQL naar een zoeksysteempje met MySQL FULLTEXT. Dan heb je al heel wat.
Als je intelligenter wilt zoeken, dan is Apache Solr of Elasticsearch erg handig als vervanging voor je database, maar het is niet verplicht voor een dergelijk systeem.
Als je een eigen server kan draaien, dan is het natuurlijk een leuk projectje om het eens vorm te geven.
De stappen zijn van: PDF -> Text - > MySQL naar een zoeksysteempje met MySQL FULLTEXT. Dan heb je al heel wat.
Als je intelligenter wilt zoeken, dan is Apache Solr of Elasticsearch erg handig als vervanging voor je database, maar het is niet verplicht voor een dergelijk systeem.
Gewijzigd op 26/01/2026 10:20:30 door - Ariën -
Met groot bedoel ik dat ik uit ervaring weet dat het opzetten van zoiets best tijd en moeite kost maar dat het onderhouden ervan er daarna bij in schiet.
Misschien dat ik het van de week even met een WAMP dat Apache Solr of Elasticsearch lokaal ga bekijken!
Je kent het waarschijnlijk wel Het mag niks kosten maar het moet er wel professioneel uit zien en functioneren ;-)
Misschien dat ik het van de week even met een WAMP dat Apache Solr of Elasticsearch lokaal ga bekijken!
Je kent het waarschijnlijk wel Het mag niks kosten maar het moet er wel professioneel uit zien en functioneren ;-)
Voor de liefhebber is het een leuk project. En gelukkig kunnen we ook vibecoden met behulp van AI. ;-)
Al raad ik wel aan dat je wel weet wat je doet.
Al raad ik wel aan dat je wel weet wat je doet.
Is er nog wat uitgekomen van het project? Of is er gekozen voor bestaande oplossingen?
Ik, en vast ook anderen, zijn benieuwd naar de afloop.
Ik, en vast ook anderen, zijn benieuwd naar de afloop.
- Ariën - op 02/02/2026 11:33:18:
Is er nog wat uitgekomen van het project? Of is er gekozen voor bestaande oplossingen?
Ik, en vast ook anderen, zijn benieuwd naar de afloop.
Ik, en vast ook anderen, zijn benieuwd naar de afloop.
Het ligt voorlopig even in het vriesvakje van de koelkast.
Zelf wil ik eerste alle magazines gescand hebben, of in ieder geval de eerste ±75 jaar.
Ondertussen eens kijken wat er voor bestaande oplossingen zijn. Misschien zoeken naar een samenwerking met het gemeente of nationale archief oid
Mar kla op 02/02/2026 15:35:39:
Het ligt voorlopig even in het vriesvakje van de koelkast.
Zelf wil ik eerste alle magazines gescand hebben, of in ieder geval de eerste ±75 jaar.
Ondertussen eens kijken wat er voor bestaande oplossingen zijn. Misschien zoeken naar een samenwerking met het gemeente of nationale archief oid
- Ariën - op 02/02/2026 11:33:18:
Is er nog wat uitgekomen van het project? Of is er gekozen voor bestaande oplossingen?
Ik, en vast ook anderen, zijn benieuwd naar de afloop.
Ik, en vast ook anderen, zijn benieuwd naar de afloop.
Het ligt voorlopig even in het vriesvakje van de koelkast.
Zelf wil ik eerste alle magazines gescand hebben, of in ieder geval de eerste ±75 jaar.
Ondertussen eens kijken wat er voor bestaande oplossingen zijn. Misschien zoeken naar een samenwerking met het gemeente of nationale archief oid
Zijn er nog updates?
Opzich is je idee helemaal niet zo ingewikkeld. Zeker als je het hebt over 1500 PDF's is dit maar een hele kleine data-set. Als je de PDF's dan al hebt omgezet naar tekst kom je met MySQL Full-Text Search al een heel eind. Zie je dat er in de toekomst nog heel veel data bij komt, dan is Meilisearch, Typesense of Elasticsearch/OpenSearch toekomstbestendiger.
Het projectje ligt even stil door onderlinge meningsverschillen in het bestuur. De bladen (de eerste ± 75 jaar iig) staan nu als PDF online op een fansite. En Google search is die aan het indexeren en ik heb al zoek resultaten op terug gevonden.
Mar kla op 11/05/2026 11:04:29:
Het projectje ligt even stil door onderlinge meningsverschillen in het bestuur. De bladen (de eerste ± 75 jaar iig) staan nu als PDF online op een fansite. En Google search is die aan het indexeren en ik heb al zoek resultaten op terug gevonden.
Die meningsverschillen is jammer, maar fijn dat je al wel een stap verder bent gekomen.
Mocht je nog wat hulp nodig hebben met je project dan horen we het graag.
Michael - op 11/05/2026 11:25:06:
Die meningsverschillen is jammer, maar fijn dat je al wel een stap verder bent gekomen.
Mocht je nog wat hulp nodig hebben met je project dan horen we het graag.
Mar kla op 11/05/2026 11:04:29:
Het projectje ligt even stil door onderlinge meningsverschillen in het bestuur. De bladen (de eerste ± 75 jaar iig) staan nu als PDF online op een fansite. En Google search is die aan het indexeren en ik heb al zoek resultaten op terug gevonden.
Die meningsverschillen is jammer, maar fijn dat je al wel een stap verder bent gekomen.
Mocht je nog wat hulp nodig hebben met je project dan horen we het graag.
top!
Misschien is paperless ngx een optie? Hoef je het wiel niet opnieuw uit te vinden.
Gekeken of dit te doen is.
Download de Smalot PdfParser en de NL stopwoorden
https://github.com/smalot/pdfparser/archive/refs/heads/master.zip
https://github.com/stopwords-iso/stopwords-nl/archive/refs/heads/master.zip
+ Smalot [map]
+ + PdfParser [map]
+ + + [alle mappen/bestanden van PdfParser]
+ index.php [dit bestand]
+ stopwords-nl.txt [NL stopwoorden]
De 3 database functies heb ik niet uitgewerkt.
Een efficiente opslag zou er zo uit kunnen zien
Tabel "bestanden" met velden id_b en bestand (lijst met unieke pad/naar/bestand.pdf)
Tabel "woorden" met velden id_w en woord (lijst met unieke woorden)
Tabel "zoeken" met velden id_b, id_w en pagina
Download de Smalot PdfParser en de NL stopwoorden
https://github.com/smalot/pdfparser/archive/refs/heads/master.zip
https://github.com/stopwords-iso/stopwords-nl/archive/refs/heads/master.zip
+ Smalot [map]
+ + PdfParser [map]
+ + + [alle mappen/bestanden van PdfParser]
+ index.php [dit bestand]
+ stopwords-nl.txt [NL stopwoorden]
De 3 database functies heb ik niet uitgewerkt.
Een efficiente opslag zou er zo uit kunnen zien
Tabel "bestanden" met velden id_b en bestand (lijst met unieke pad/naar/bestand.pdf)
Tabel "woorden" met velden id_w en woord (lijst met unieke woorden)
Tabel "zoeken" met velden id_b, id_w en pagina
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?php
// maak recursief een array met alle pad/naar/bestand.pdf
function getPdfFilenames ($path) {
$rIterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)
);
$pdfs = [];
foreach ($rIterator as $file) {
if ($file->isFile() && strtolower($file->getExtension()) == 'pdf') {
$pdfs[] = $file->getPathname();
}
}
return $pdfs;
}
// maak een array met alle woorden
function createWordArray ($text, $stopwords) {
// naar lowercase en vervang accenten
$text = mb_strtolower($text);
$accents = [
'a' => 'àáâãäå', 'c' => 'ç', 'e' => 'èéêë', 'i' => 'ìíîï',
'n' => 'ñ', 'o' => 'òóôõö', 'u' => 'ùúûü', 'y' => 'ýÿ'
];
foreach ($accents as $key => $value) {
preg_replace('/['.$value.']/u', $key, $text);
}
// verwijder alles behalve letters/cijfers/spaties
$text = preg_replace('/[^a-z0-9\s]/u', ' ', $text);
// meerdere spaties vervangen door enkele spatie
$text = preg_replace('/\s+/', ' ', $text);
// split in array van woorden
$words = explode(' ', trim($text));
// verwijder stopwoorden
$words = array_filter($words, function($word) use ($stopwords) {
return !in_array($word, $stopwords);
});
// verwijder lege strings en korte woorden
$words = array_filter($words, function($word) {
return strlen($word) >= 3;
});
// sorteer woorden en verwijder duplicaten
sort($words);
return array_unique($words);
}
// PdfParser
$dir = str_replace('\\', '/', __DIR__);
require_once $dir.'/alt_autoload.php';
use Smalot\PdfParser\Parser;
$parser = new \Smalot\PdfParser\Parser();
// array met alle pdf's (pad/naar/bestand.pdf)
$pdfFolder = 'files/clubbladen/';
$pdfFiles = getPdfFilenames ($pdfFolder);
// stopwords file https://github.com/stopwords-iso/stopwords-nl/
$stopwords = file('stopwords-nl.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$stopwords = array_map('trim', $stopwords);
// maak db connectie
//$conn = dbConnect($conf);
// doorloop alle pdf's
foreach ($pdfFiles as $pdfFile) {
$pdf = $parser->parseFile($pdfFile);
$text = '';
$metaData = $pdf->getDetails();
if (isset($metaData['Pages'])) {
for ($page = 0; $page < $metaData['Pages']; $page++) {
$text = $pdf->getPages()[$page]->getText();
$words = createWordArray($text, $stopwords);
$realPage = $page + 1;
echo '<pre>';
print_r (['Bestand' => $pdfFile, 'Pagina' => $realPage]);
print_r ($words);
echo '</pre>';
//dbUpdateWords ($conn, $pdfFile, $realPage, $words);
}
}
}
// verbreek db connectie
// dbDisconnect($conn)
// maak recursief een array met alle pad/naar/bestand.pdf
function getPdfFilenames ($path) {
$rIterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)
);
$pdfs = [];
foreach ($rIterator as $file) {
if ($file->isFile() && strtolower($file->getExtension()) == 'pdf') {
$pdfs[] = $file->getPathname();
}
}
return $pdfs;
}
// maak een array met alle woorden
function createWordArray ($text, $stopwords) {
// naar lowercase en vervang accenten
$text = mb_strtolower($text);
$accents = [
'a' => 'àáâãäå', 'c' => 'ç', 'e' => 'èéêë', 'i' => 'ìíîï',
'n' => 'ñ', 'o' => 'òóôõö', 'u' => 'ùúûü', 'y' => 'ýÿ'
];
foreach ($accents as $key => $value) {
preg_replace('/['.$value.']/u', $key, $text);
}
// verwijder alles behalve letters/cijfers/spaties
$text = preg_replace('/[^a-z0-9\s]/u', ' ', $text);
// meerdere spaties vervangen door enkele spatie
$text = preg_replace('/\s+/', ' ', $text);
// split in array van woorden
$words = explode(' ', trim($text));
// verwijder stopwoorden
$words = array_filter($words, function($word) use ($stopwords) {
return !in_array($word, $stopwords);
});
// verwijder lege strings en korte woorden
$words = array_filter($words, function($word) {
return strlen($word) >= 3;
});
// sorteer woorden en verwijder duplicaten
sort($words);
return array_unique($words);
}
// PdfParser
$dir = str_replace('\\', '/', __DIR__);
require_once $dir.'/alt_autoload.php';
use Smalot\PdfParser\Parser;
$parser = new \Smalot\PdfParser\Parser();
// array met alle pdf's (pad/naar/bestand.pdf)
$pdfFolder = 'files/clubbladen/';
$pdfFiles = getPdfFilenames ($pdfFolder);
// stopwords file https://github.com/stopwords-iso/stopwords-nl/
$stopwords = file('stopwords-nl.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$stopwords = array_map('trim', $stopwords);
// maak db connectie
//$conn = dbConnect($conf);
// doorloop alle pdf's
foreach ($pdfFiles as $pdfFile) {
$pdf = $parser->parseFile($pdfFile);
$text = '';
$metaData = $pdf->getDetails();
if (isset($metaData['Pages'])) {
for ($page = 0; $page < $metaData['Pages']; $page++) {
$text = $pdf->getPages()[$page]->getText();
$words = createWordArray($text, $stopwords);
$realPage = $page + 1;
echo '<pre>';
print_r (['Bestand' => $pdfFile, 'Pagina' => $realPage]);
print_r ($words);
echo '</pre>';
//dbUpdateWords ($conn, $pdfFile, $realPage, $words);
}
}
}
// verbreek db connectie
// dbDisconnect($conn)
Gewijzigd op 12/05/2026 11:44:45 door Ron Kr.




