Jörg: preg_replace bei sehr großen Strings

Hallo Forum,

ich hatte einen recht schönen Bilderwechselkreislauf erstellt, der sich einer Regex bediente und ein Bild eines Fliesstextes durch ein neues Bild ersetzte. Hierbei konnte ich auf ein Uploadverzeichnis setzen, dessen Nutzung eine Berechtigung voraussetzt.

Daher hatte ich in der Regex einen festen Anker, anhand dessen ich wußte, was im Fliesstext zu ersetzen war.

Nun möchte ich aber darauf umstellen, anstelle der Image-Url ein base64-codiertes Images einzusetzen. Nachteil ist nun, dass neben der grossen Menge an Daten auch mein "Anker" des festen Verzeichnisses wegfällt, anhand dessen ich wußte, ob das Bild ein "Austauschbild" war oder nicht.

Da ich immer das letzte "Austauschbild" kenne, könnte ich ja über einen Vergleich base64(letztesBild) == BildImFliesstext prüfen, ob das Bild stehen bleibt oder ausgetuascht wird. Allerdings sind die zu vergleichenden Datenmengen recht groß.

Ist es sinn voll, diesen Vergleich zu machen oder macht ein Hash-Vergleich der Strings mehr DSinn oder wie geht man das am besten an?

Jörg

  1. Hallo Jörg,

    Nun möchte ich aber darauf umstellen, anstelle der Image-Url ein base64-codiertes Images einzusetzen.

    Du möchtest in einem Fließtext eine data-URL nutzen? Autsch?! Klingt schwer zu handhaben für den Autor.

    Du möchtest [img]data:image/jpeg;base64,(hexhexhexhex)[/img] finden und die data-URL darin durch eine andere ersetzen? Wobei es nicht zwingend jpeg sein muss, es gibt ja auch noch andere image-Typen.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      Du möchtest in einem Fließtext eine data-URL nutzen? Autsch?! Klingt schwer zu handhaben für den Autor.

      Doch, leider ist es einfach, denn mein Editor setzt das bei copy und paste automatisch um. Was das Image aus dem Bilderwechsel angeht, da mache ich das dann beim Puload über php. Insofern Bedienung ist einfach.

      Du möchtest [img]data:image/jpeg;base64,(hexhexhexhex)[/img] finden und die data-URL darin durch eine andere ersetzen? Wobei es nicht zwingend jpeg sein muss, es gibt ja auch noch andere image-Typen.

      Genau das ist das Problem. Und die ggf. weiteren vorhandenen [img]data:image/jpeg;base64,(hexhexhexhex)[/img] sollen unbehelligt bleiben. Nur das über den Upload erstellte Image soll ersetzt werden.

      Jörg

      1. Hallo Jörg,

        die data-URL zu matchen ist doch überhaupt kein Problem, wenn Du ausschließlich data-URLs matchen willst. Oder soll die Regex die alten URL auch matchen? Das sollte sich mit einem gutgezielten | in den Griff bekommen lassen.

        Nur das über den Upload erstellte Image soll ersetzt werden.

        Da ist die Frage: können data-URL nur über den Upload entstehen? Oder auch auf anderem Weg? Die könnte man nämlich nicht unterscheiden.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          Nur das über den Upload erstellte Image soll ersetzt werden.

          Da ist die Frage: können data-URL nur über den Upload entstehen? Oder auch auf anderem Weg? Die könnte man nämlich nicht unterscheiden.

          Genau hier ist das Problem, was zu meinem Post führte. Es können zahlreiche Data-URLs entstehen, wovon aber nur die über den Upload entstandene ersetzt werden soll.

          Ich habe das jetzt so gemacht:

          Ich habe eine zusätzliche Tabelle in der DB angelegt, die (u.a.) den Data-URL-String des Uploads und das Uploaddatum enthält.

          Anschließend gehe ich (im Fall eines Uploads) wie folgt vor:

          Erst selektiere ich den Data-URL-String des letzten Uploads
          Dann lade ich den neuen Upload hoch Dann update ich alle Data-Upload-Daten der DB, bis auf den soeben hoich geladenen (bischen Speicher sparen😉)

          Dann führe ich den Vergleich durch, allerdings nicht mehr über preg_replace(), sondern über str_replace(), das ist etwas sparsamer.

          Somit werden nur die Data-Urls ausgetauscht, die ich auch wirklich austauschen will.

          Jörg

          1. Hallo Jörg,

            die (u.a.) den Data-URL-String des Uploads und das Uploaddatum enthält.

            Oha, das ist fett. Da reicht ggf. schon ein Hash.

            Aber wie sieht es denn mit der nachträglichen Bearbeitung aus? Kann jemand einen solchen Datenklops nachträglich bearbeiten? Wenn ja, kann ja aller möglicher Unfug in die data-URL eingetragen werden, das ist durchaus riskant.

            Wenn keine Nachbearbeitung möglich ist, könntest Du auch mit modifizierten data-URLs arbeiten. Du musst die Bilder für die HTML Anzeige ohnehin aufbereiten, d.h. du könntest die Uploads als data:image/jpeg+upload;base64,hexhex speichern, und das +upload für die HTML Anzeige rausschmeißen. Das ist ein einfacher str_replace (wenn es nur jpeg ist) und ein nur unwesentlich komplizierterer preg_replace, wenn mehr als ein Image-Typ möglich ist.

            Die Frage, warum Du überhaupt mit data-URLs arbeiten willst statt die Bilddatei auf Platte zu legen, stelle ich mir auch noch. Wenn Du vermeiden willst, unbenutzte Bilddateien finden und entsorgen zu müssen, ok, aber das Problem hast Du durch die zusätzliche Tabelle in der DB jetzt auch.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo Rolf,

              die (u.a.) den Data-URL-String des Uploads und das Uploaddatum enthält.

              Oha, das ist fett. Da reicht ggf. schon ein Hash.

              Hab ich auch schon dran gedacht.

              Aber wie sieht es denn mit der nachträglichen Bearbeitung aus? Kann jemand einen solchen Datenklops nachträglich bearbeiten? Wenn ja, kann ja aller möglicher Unfug in die data-URL eingetragen werden, das ist durchaus riskant.

              Nicht wirklich. Der User kann nicht zwischen Editor und BBcode umschalten. Er kann natürlich theoretisch allerlei Blödsinn an das Script senden, aber nicht über den Editor selber.

              Wenn keine Nachbearbeitung möglich ist, könntest Du auch mit modifizierten data-URLs arbeiten. Du musst die Bilder für die HTML Anzeige ohnehin aufbereiten, d.h. du könntest die Uploads als data:image/jpeg+upload;base64,hexhex speichern, und das +upload für die HTML Anzeige rausschmeißen. Das ist ein einfacher str_replace (wenn es nur jpeg ist) und ein nur unwesentlich komplizierterer preg_replace, wenn mehr als ein Image-Typ möglich ist.

              Daran hatte ich hzuerst gedacht. Dann aber ist das Image im Editor nicht sichtbar, weil ich dort nicht genau weiß, wo ich austauschen muss.

              Die Frage, warum Du überhaupt mit data-URLs arbeiten willst statt die Bilddatei auf Platte zu legen, stelle ich mir auch noch. Wenn Du vermeiden willst, unbenutzte Bilddateien finden und entsorgen zu müssen, ok, aber das Problem hast Du durch die zusätzliche Tabelle in der DB jetzt auch.

              Gute Frage, denn mir selber gefällt der Data-Url.Code auch nicht. Aber wenn aus der Anwendung heraus eine Mail versendet wird, wird die Data-Url sofort in ein Image gewandelt, während die meisten Email-Clients externe Images erstmal blockieren. 😕

              Jörg

              1. Hallo,

                Gute Frage, denn mir selber gefällt der Data-Url.Code auch nicht. Aber wenn aus der Anwendung heraus eine Mail versendet wird, wird die Data-Url sofort in ein Image gewandelt, während die meisten Email-Clients externe Images erstmal blockieren. 😕

                Habe aber gerade jetzt festgestellt, dass verschiedene Mailclients sowohl die erste, wie auch die zweite Variante blocken 😕

                Ich meine, ich verstehs ja, aber gibts denn gar keine Möglichkeit, ein kleines Image (Firmenlogo o.ä.) in eine Mail einzuschleusen, ohne das der Empfängerclient das blockt?

                Weil ansonsten hätte ich mir den ganzen URL-Data-Kram wirklich sparen können/sollen (?).

                Achso, versandt werden die Emails übrigens mit php-mailer, falls das relevant sein sollte.

                Jörg

                1. Hallo Jörg,

                  Habe aber gerade jetzt festgestellt, dass verschiedene Mailclients sowohl die erste, wie auch die zweite Variante blocken 😕

                  was meinst du mit erster und zweiter Variante? Externe Bilder vs. data-URLs? Weil ... die data-URLs sollten eigentlich unproblematisch sein (nur unhandlich).

                  Ich meine, ich verstehs ja, aber gibts denn gar keine Möglichkeit, ein kleines Image (Firmenlogo o.ä.) in eine Mail einzuschleusen, ohne das der Empfängerclient das blockt?

                  Doch, natürlich: Pack das Bild in die Mailnachricht rein. Technisch gesehen ist das Bild dann ein Dateianhang, hat aber in seinen Sub-Headern eine bestimmte Kennung, eine sogenannte Content ID, und wird aus dem Mailtext mit cid: gefolgt von dieser Content ID referenziert. Schau dir mal ein paar e-Mails mit Bildern, die du selbst bekommen hast, im Quelltext an.

                  Weil ansonsten hätte ich mir den ganzen URL-Data-Kram wirklich sparen können/sollen (?).

                  Hättest du auch, meiner Ansicht nach. 😉

                  Live long and pros healthy,
                   Martin

                  --
                  Wer respektiert werden will, sollte zunächst damit anfangen, andere zu respektieren.
                  1. Hallo Martin,

                    was meinst du mit erster und zweiter Variante? Externe Bilder vs. data-URLs? Weil ... die data-URLs sollten eigentlich unproblematisch sein (nur unhandlich).

                    Leider sind die Data-Urls nicht nur extrem unhandlich (weil groß), sondern sie werden auch teilweise geblockt. Würden sie immer geblockt, würde ich nach einen Fehler suchen, aber sie werden in derselben Mail je nach Client geblockt. Outlook tut sich hier ganz besonders hervor.

                    Doch, natürlich: Pack das Bild in die Mailnachricht rein. Technisch gesehen ist das Bild dann ein Dateianhang, hat aber in seinen Sub-Headern eine bestimmte Kennung, eine sogenannte Content ID, und wird aus dem Mailtext mit cid: gefolgt von dieser Content ID referenziert. Schau dir mal ein paar e-Mails mit Bildern, die du selbst bekommen hast, im Quelltext an.

                    Da sitz ich gerade schon dran. Weil es mir gelungen ist, ein solches embedded Image auch im POutlook sichtbar zu machen. Ist etwas komplizierter in den Emailbody einzupflegen, aber dafür muss ich deutlich weniger Daten speichern. Das Image ist ja dann nur noch ein Verweis auf das Image und nicht das Image (als base64-Daten selber).

                    Weil ansonsten hätte ich mir den ganzen URL-Data-Kram wirklich sparen können/sollen (?).

                    Hättest du auch, meiner Ansicht nach. 😉

                    Ist wahr? Kannst Du mir nochmal genau sagen, warum? Bei mir wars nur empirisch begründet, aber Du sagtest ja, die Data-Urls sollten ansich keine Probleme machen. Warum hätte ichs mir dann Deiner Meinung nach (auch) sparen könnnen?

                    Gruß, Jörg

                    1. Hallo,

                      Leider sind die Data-Urls nicht nur extrem unhandlich (weil groß), sondern sie werden auch teilweise geblockt. Würden sie immer geblockt, würde ich nach einen Fehler suchen, aber sie werden in derselben Mail je nach Client geblockt. Outlook tut sich hier ganz besonders hervor.

                      dann tippe ich mal, dass die Länge tatsächlich das Problem ist. Es gibt keine allgemeine Festlegung, wie lang URLs sein dürfen, darum gibt es in den meisten Programmen willkürliche Beschränkungen. Kann also gut sein, dass deine data-URLs je nach Client ab einer bestimmten Länge Ärger machen.

                      Doch, natürlich: Pack das Bild in die Mailnachricht rein. Technisch gesehen ist das Bild dann ein Dateianhang, hat aber in seinen Sub-Headern eine bestimmte Kennung, eine sogenannte Content ID, und wird aus dem Mailtext mit cid: gefolgt von dieser Content ID referenziert. Schau dir mal ein paar e-Mails mit Bildern, die du selbst bekommen hast, im Quelltext an.

                      Da sitz ich gerade schon dran.
                      Weil es mir gelungen ist, ein solches embedded Image auch im POutlook sichtbar zu machen.
                      Ist etwas komplizierter in den Emailbody einzupflegen, aber dafür muss ich deutlich weniger Daten speichern. Das Image ist ja dann nur noch ein Verweis auf das Image und nicht das Image (als base64-Daten selber).

                      An der Datenmenge ändert sich nichts, denn anstatt im Mail-Text hast du die Daten dann halt im Attachment als base64-Block. Aber das ist dann ein seit über 20 Jahren etabliertes Konzept.

                      Weil ansonsten hätte ich mir den ganzen URL-Data-Kram wirklich sparen können/sollen (?).

                      Hättest du auch, meiner Ansicht nach. 😉

                      Ist wahr?
                      Kannst Du mir nochmal genau sagen, warum?

                      Nicht so richtig fundiert, es ist mehr so ein Bauchgefühl. Und das Bauchgefühl sagt, dass data-URLs nur ein Notbehelf für Fälle sind, wo's anders nicht mehr geht.

                      Bei mir wars nur empirisch begründet, aber Du sagtest ja, die Data-Urls sollten ansich keine Probleme machen. Warum hätte ichs mir dann Deiner Meinung nach (auch) sparen könnnen?

                      Weil mir gerade kein Kontext einfällt, bei dem man die Bilder nicht auch separat speichern und einfach referenzieren kann. Das muss aber nichts heißen.

                      Live long and pros healthy,
                       Martin

                      --
                      Wer respektiert werden will, sollte zunächst damit anfangen, andere zu respektieren.
                      1. Hallo Martin,

                        dann tippe ich mal, dass die Länge tatsächlich das Problem ist. Es gibt keine allgemeine Festlegung, wie lang URLs sein dürfen, darum gibt es in den meisten Programmen willkürliche Beschränkungen. Kann also gut sein, dass deine data-URLs je nach Client ab einer bestimmten Länge Ärger machen.

                        Dann bin ich doppelt froh, dass ich von den Data-Urls wider los bin 😉 Weil das mir zu unberechenbar ist.

                        Ist etwas komplizierter in den Emailbody einzupflegen, aber dafür muss ich deutlich weniger Daten speichern. Das Image ist ja dann nur noch ein Verweis auf das Image und nicht das Image (als base64-Daten selber).

                        An der Datenmenge ändert sich nichts, denn anstatt im Mail-Text hast du die Daten dann halt im Attachment als base64-Block. Aber das ist dann ein seit über 20 Jahren etabliertes Konzept.

                        Doch, doich, die Datenmenge ändert sich. Ich schrieb ja extra nicht "dafür muss ich deutlich weniger Daten senden", sondern "dafür muss ich deutlich weniger Daten speichern". Es ging mir tatsächlich um das speichern in der DB, wo ich schon von text mindestens auf mediumtext, wenn nicht gar loongtext gehen musste.

                        Nicht so richtig fundiert, es ist mehr so ein Bauchgefühl. Und das Bauchgefühl sagt, dass data-URLs nur ein Notbehelf für Fälle sind, wo's anders nicht mehr geht.

                        Bei mir wars nur empirisch begründet, aber Du sagtest ja, die Data-Urls sollten ansich keine Probleme machen. Warum hätte ichs mir dann Deiner Meinung nach (auch) sparen könnnen?

                        Weil mir gerade kein Kontext einfällt, bei dem man die Bilder nicht auch separat speichern und einfach referenzieren kann. Das muss aber nichts heißen.

                        Dann deckt sich aber Dein gefühl ganz gut mit meinen heutigen Erfahrungen. Insofern versuch ichs jetzt mal "embedded" ;)

                        Danke für Deine Antwort,

                        Jörg

                        1. Hallo,

                          mir gelingt es (mitunter), ein Image als embedded in einer Mail (phpmailer) unterzubringen.

                          Aber irgendwie habe ich gerade mal wieder ein seltsames Problem:

                          $pdfText = 'Embedded Image: <img alt="PHPMailer" src="cid:my-Bild"> Here is an image!';
                          //$pdfText = 'Embedded Image: <img alt="PHPMailer" scr="cid:my-Bild"> Zeile 6';
                          

                          funktioniert (ich sehe das Image in der Mail)

                          //$pdfText = 'Embedded Image: <img alt="PHPMailer" src="cid:my-Bild"> Here is an image!';
                          $pdfText = 'Embedded Image: <img alt="PHPMailer" scr="cid:my-Bild"> Zeile 6';
                          
                          

                          Funktioniert nicht (ich sehe das Image nicht, es wird der Mail aber als Anhang angehängt)

                          Sieht einer von Euch, worin sich die beiden Zeilen (wesentlich) voneinander unterscheiden? 😕

                          Jörg

                          1. Hallo,

                            Sieht einer von Euch, worin sich die beiden Zeilen (wesentlich) voneinander unterscheiden? 😕

                            Wie oft denn noch? scr ≠ src
                            Bitte nutze einen Editor mit Syntaxhighlighting.

                            Gruß
                            Kalk

                            1. Hallo Tabellenkalk,

                              Wie oft denn noch? scr ≠ src
                              Bitte nutze einen Editor mit Syntaxhighlighting.

                              Ach herrje... ich sollte eine Pause einlegen 😉 Danke für Deinen Blick auf die beiden Zeilen!👍

                              Bitte nutze einen Editor mit Syntaxhighlighting.

                              Hm, PhPStorm meckert nicht bei scr und highlightet kein src. Sieht Beides identisch aus.

                              Jörg

                              1. Tach!

                                Hm, PhPStorm meckert nicht bei scr und highlightet kein src. Sieht Beides identisch aus.

                                Doch, grundsätzlich macht er das. Selbst innerhalb von Strings erkennt er HTML.

                                dedlfix.

                        2. Dieser Beitrag wurde gelöscht: Der Beitrag ist ein Duplikat eines anderen Beitrags.