skip to Main Content

I’m an amateur web programmer. From time to time I like to build something for personal use, taking a lot of pleasure from the result when a script finally does what I want it to do. So I learn as I go, but now I’m stuck and I hope someone here would be willing to take a look at what I’m doing.

I’m working on a project that takes text files from a folder and searches the text of each file for specific keywords that correspond to image files that I’m trying to insert in the text as an html image tag using php. I got it almost working: the correct images get inserted at the desired points, and text files that do not contain a keyword remain untouched, but the text files that have images inserted are doubled: one text file with added image and one original text file. I have tried different approaches but either it doesn’t work at all, or the text files with inserted images are duplicated.

Where lies the foult? Am I going at it the wrong way?

Here is my code:

<?php
$path = // array of .txt-filenames with plain tekst
$imagepath = // array of .jpg-filenames

foreach ($path as $file) {

$haystack = file_get_contents("$file");

    foreach ($imagepath as $imagefile) {
        $needle = $imagefile;
        $position = strpos($haystack,$needle);

        if ($position !== false) {$output = substr_replace($haystack, "<img src='$imagefile'>", $position, 0);} else {$output = $haystack;}
              
        echo $output; }

}
?>

2

Answers


  1. If you have two images in $imagepath and the second one is not found by strpos then I believe $output = $haystack; will revert previous changes.

    Here’s a code snippet with more meaningful variables.

    <?php
    $textFiles = [];
    $imageFileNames = [];
    
    foreach ($textFiles as $file) {
        $fileContent = file_get_contents($file);
    
        foreach ($imageFileNames as $imageFileName) {
            $position = strpos($fileContent, $imageFileName);
    
            if ($position !== false) {
                $fileContent = substr_replace($fileContent, "<img src='$imageFileName' />", $position, 0);
            }
        }
        file_put_contents($file, $fileContent);
        echo $fileContent; // if you want to debug
    }
    

    We could argue that we’re rewriting $file even if $fileContent has not changed is useless but that’s another story!

    Login or Signup to reply.
  2. You are building the $output string inside of a nested loop, so every time your inner loop restarts and finds whitelisted image filenames (even ones already affected), another replacement is made.

    I recommend avoiding this problem by avoiding the nested loop. Build a regex pattern of all qualifying image names, then make all possible replacements in each iterated file.

    • If $path is an array of filepaths, then call it $paths.
    • If $imagepath is an array of image filenames, then call it $imageNames.
    $piped = implode('|', array_map('preg_quote', $imageNames));
    foreach ($paths as $file) {
        echo preg_replace(
                 "#$piped#",
                 '<img src="$0">$0',
                 file_get_contents($file)
             );
        echo "n---n"; // create some visual separation between files
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search