1

I want to delete a line which contains something given by the $_POST['link']

It already works with the .csv-File. At this point, the code for the .txt-File does nohting.

My php code

//txt
$txt = file('../textFiles/websites.txt');
$fpTXT = fopen('../textFiles/websites.txt', 'w');
foreach ($txt as $lines) {
  if (!str_contains($lines[2], strval($_POST['link']))) {
    fwrite($fpTXT, $lines);
  }
}
fclose($fpTXT);

the trigger with js

<!-- Delete-Function -->
    <script>
        async function deleteRequest(elem) {
            $.ajax({
                type: 'POST',
                url: '/sites/deleting.php',
                dataType: 'html',
                data: {
                    'link': elem
                }
            });
            location.reload();
        };
    </script>
</head>


<!-- Delete Icon -->
    <?php $delBtn = "<td><button class='delete' onclick=\"deleteRequest(this.parentNode.parentNode.getElementsByTagName('td')[2].innerText)\"><i class='material-icons'>&#xE872;</i></button></td>"; ?>

code for the csv (above the txt-code)

//CSV
$csv = array_map('str_getcsv', file('../textFiles/websites.csv'));
$fpCSV = fopen('../textFiles/websites.csv', 'w');
foreach ($csv as $fields) {
  if (!str_contains($fields[2], strval($_POST['link']))) {
    fputcsv($fpCSV, $fields);
  }
}
fclose($fpCSV);

2 lines from the .txt-File

enter image description here

MtoseD
  • 33
  • 5
  • Have you debugged the values of `$lines[2]` to see if any of them contain `$_POST['link']`? – rickdenhaan Aug 18 '21 at 11:24
  • @rickdenhaan the output is just 6 times (amount of lines in the file) the second letter of the line, which I want to delete – MtoseD Aug 18 '21 at 11:29
  • Uh, you want to delete *the second letter of the line*? Perhaps you'd better include in the question an example with two lines from that file, and an instance of a posted value. – LSerni Aug 18 '21 at 11:32
  • no, actually a particular line – MtoseD Aug 18 '21 at 11:36

2 Answers2

4

The "$lines" you get from file() is not the same thing as a CSV record. Each of those is a single line, so $lines[2] refers to the third character of that line:

$lines = "https://www.google.com\n";

$lines[2] is just a "t".

While in a CSV record, you would have

$lines = [ "A1", "B1", "C1", "D1" ]

and here, $lines[2] is "C1".

You should filter the text lines to delete the one you don't want

$outputFile = '../textFiles/websites.txt';

$remove = strval($_POST['link']);
$txt = array_filter(
    file($outputFile),
    function ($eachLine) use ($remove) {
        return !str_contains($eachLine, $remove);
        // or equivalently,
        // return false === strpos($eachLine, $remove)
        // In all cases, consider that if someone sends ".",
        // you will remove ALL sites, since they'll all have a dot in their site name.
        // So maybe is better
        // return $remove !== trim($eachLine)
        // (the "trim" is needed to get the carriage return at the end of line out of the comparison, which otherwise would always fail).
    }
);

// Now you need to write the cleaned file
file_put_contents($outputFile, implode('', $txt));
LSerni
  • 55,617
  • 10
  • 65
  • 107
  • thank you so much :) **solved it for me** – MtoseD Aug 18 '21 at 11:41
  • @MtoseD keep in mind to check out those edge cases I commented in the function. "str_contains" alone may cause unexpected and unwanted results. – LSerni Aug 18 '21 at 15:16
2

If you just want to replace a word or sentence from the file, you could easily do this with str_replace:

$file = '../textFiles/websites.txt';
$findText = $_POST['link'];
file_put_contents($file, str_replace($findText, '', file_get_contents($file)));
  • be aware that, this way, you will create a "gap" in the text file; the `$findText` ought to **also include the file separator** ("\n" or "\r\n"). This will also avoid the edge case - contrived, but *still* - where you ask to remove "https://mail.google.com" and you inadvertently transform "https://mail.google.compressor.net" into "pressor.net". However, +1 for efficiency. – LSerni Aug 18 '21 at 15:15