Jürgen1999: string vergleichen in php

Moinsen. Müßte n Bissl was ändern in nem WP-Plugin.

Und zwar soll im folgenden Ausdruck PHP-Code: <?php if ( get_post_meta( $post->ID, 'kontaktperson_vorname', true) != '' ) : ?> der Vergleich etwas anderes prüfen.

Es soll nicht auf "ist nicht leer", sondern auf "beinhaltet einen String, der mit VRVR anfängt" geprüft werden...zB VRVRerwin oder sowas...

Vielen lieben Dank!!

  1. @@Jürgen1999

    Es soll … "beinhaltet einen String, der mit VRVR anfängt" geprüft werden

    Was denn nun: „beïnhaltet VRVR“ oder „fängt mit VRVR an“?

    Wie auch immer: mb_strpos() (für Strings) bzw. strpos() für was auch immer.

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    1. Tach!

      Es soll … "beinhaltet einen String, der mit VRVR anfängt" geprüft werden

      Was denn nun: „beïnhaltet VRVR“ oder „fängt mit VRVR an“?

      Oder beides, wenn es ungenau ausgedrückt war, und stattdessen gemeint ist: "beinhaltet ein Wort an beliebiger Position, das mit VRVR anfängt". Dieser Fall wird dann wohl einen Regex erfordern, damit man Wortgrenzen erkennen kann.

      Ich gehe aber davon aus, dass aus technischer Sicht gemeint war: der Aufruf der Funktion get_post_meta() soll einen String liefern/zurückgeben, der mit VRVR anfängt. Oder aus Anwendersicht: die Eingabe soll mit VRVR anfangen.

      Wie auch immer: mb_strpos() (für Strings) bzw. strpos() für was auch immer.

      Die Antwort ist sehr knapp, denn sie berücksichtigt so einiges nicht.

      Man kann mit der Multibyte-Funktion mb_strpos() arbeiten. Diese Multibyte-Funktionen können im Allgemeinen nur dann richtig arbeiten, wenn die Kodierung bekannt ist und entweder als optionaler Parameter angegeben wird, oder wenn sie generell mit mb_internal_encoding() gesetzt worden ist. In einem System, das man nicht kennt, sollte man aber lieber nicht die generelle Kodierungsbehandlung umstellen, damit der Rest des Programms nicht beeinflusst wird.

      In diesem Fall ist es aber nicht notwendig die mb-Variante zu verwenden. Gefragt ist keine genaue Position, die bei Multibyte-Strings je nach Kodierung an unterschiedlichen Bytepositionen sein könnte, sondern lediglich, ob der Anfang auf bestimmte Weise beginnt, und das ist immer die Position 0. Es kommt lediglich darauf an, dass die Kodierung der Eingabe mit der Kodierung der Code-Datei übereinstimmt. Und gehen wir mal davon aus, dass lediglich ISO-8859-1 (oder 15) oder UTF-8 Verwendung finden, dann muss die Kodierung nur dann übereinstimmen, wenn Nicht-ASCII-Zeichen im gesuchten Teilstring vorkommen. Ein a beispielsweise ist in ISO-8859-1 gleich kodiert wie eins in UTF-8. Ein ä wäre das nicht, und der Vergleich wird fehlschlagen. Ansonsten ist es für den vorliegenden Fall kein Problem, die Kodierung unbeachtet zu lassen. Das ist zwar ein wenig schlampig, jedoch ändert sich das Ergebnis dadurch nicht.

      Apropos Ergebnis, hier muss man in jedem Fall (mb_strpos oder strpos) darauf achten, dass die Positionsangabe 0 mit dem false für "gar nicht enthalten" verwechselt werden kann, wenn man einen einfachen Vergleich mit == oder != verwendet. Hier muss typsicher mit === oder !== vergleichen werden. Die Beispiele #1 und #2 im PHP-Handbuch zeigen die Anwendung von strpos() sogar fast passend für den vorliegenden Fall, die Prüfung müsste statt false nur auf 0 erfolgen.

      dedlfix.

      1. @@dedlfix

        In diesem Fall ist es aber nicht notwendig die mb-Variante zu verwenden.

        In der Tat:

        $haystack = '🎷🎸🎹🎺🎻';
        $needle = '🎸🎹';
        
        var_dump(strpos($haystack, $needle));     // int(4)
        var_dump(mb_strpos($haystack, $needle));  // int(1)
        

        Apropos Ergebnis, hier muss man in jedem Fall (mb_strpos oder strpos) darauf achten, dass die Positionsangabe 0 mit dem false für "gar nicht enthalten" verwechselt werden kann, wenn man einen einfachen Vergleich mit == oder != verwendet. Hier muss typsicher mit === oder !== vergleichen werden.

        Deshalb steht das ja auch fett eingerahmt in der Doku.

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. Tach!

          In diesem Fall ist es aber nicht notwendig die mb-Variante zu verwenden.

          In der Tat:

          $haystack = '🎷🎸🎹🎺🎻';
          $needle = '🎸🎹';
          
          var_dump(strpos($haystack, $needle));     // int(4)
          var_dump(mb_strpos($haystack, $needle));  // int(1)
          

          Das ist ein Versuchsaufbau der nicht zur Aufgabenstellung "beginnt mit" passt. Der folgende Code entspräche dem.

          $haystack = '🎸🎹🎺🎻';
          $needle = '🎸🎹';
          
          var_dump(strpos($haystack, $needle));     // int(0)
          var_dump(mb_strpos($haystack, $needle));  // int(0)
          

          Apropos Ergebnis, hier muss man in jedem Fall (mb_strpos oder strpos) darauf achten, dass die Positionsangabe 0 mit dem false für "gar nicht enthalten" verwechselt werden kann, wenn man einen einfachen Vergleich mit == oder != verwendet. Hier muss typsicher mit === oder !== vergleichen werden.

          Deshalb steht das ja auch fett eingerahmt in der Doku.

          Nicht bei mb_strpos(). Da ist es aber genauso nötig.

          dedlfix.

          1. @@dedlfix

            $haystack = '🎷🎸🎹🎺🎻';
            $needle = '🎸🎹';
            
            var_dump(strpos($haystack, $needle));     // int(4)
            var_dump(mb_strpos($haystack, $needle));  // int(1)
            

            Das ist ein Versuchsaufbau der nicht zur Aufgabenstellung "beginnt mit" passt.

            Aber zu „Gefragt ist keine genaue Position.“

            LLAP 🖖

            --
            „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
            1. zunächst vielen Dank für eure Mühe! Ich kann größtenteils gut nachvollziehen, aber keinesfalls nachtesten - mehr als try'n'error ist nicht drin und in dem Fall megaaufwändig. Ich habe mir grade ne vermutete Vereinfachung einfallen lassen: Es soll abgefragt werden: anstatt "=VRVR*" lieber "strlength>14" ... das sollte sich doch relativ leicht ausdrücken lassen ohne auszuholen ?? Also, wenn der String länger als 14 Stellen ist, dann... Ich weiß, das entspricht im Allgemeinen nicht dem Ansatz hier, aber ihr helft mir nur wirklich, wenn ich das als fertigen plug'n'play fähigen Ausdruck bekommen könnte! DANKE!!

              1. Tach!

                Es soll abgefragt werden: anstatt "=VRVR*" lieber "strlength>14" ... das sollte sich doch relativ leicht ausdrücken lassen ohne auszuholen ?? Also, wenn der String länger als 14 Stellen ist, dann...

                ... ist das eine andere Aufgabenstellung als im Ausgangsposting. Was also soll es denn nun wirklich sein?

                Ich weiß, das entspricht im Allgemeinen nicht dem Ansatz hier, aber ihr helft mir nur wirklich, wenn ich das als fertigen plug'n'play fähigen Ausdruck bekommen könnte!

                Das wird dir nichts nützen, wenn der aufgrund ungenau formulierter Anforderungen nicht auf das eigentliche Problem passt.

                dedlfix.

            2. Tach!

              $haystack = '🎷🎸🎹🎺🎻';
              $needle = '🎸🎹';
              
              var_dump(strpos($haystack, $needle));     // int(4)
              var_dump(mb_strpos($haystack, $needle));  // int(1)
              

              Das ist ein Versuchsaufbau der nicht zur Aufgabenstellung "beginnt mit" passt.

              Aber zu „Gefragt ist keine genaue Position.“

              Ja, das schon, aber war das denn im OP gefragt? Jedenfalls widerlegt das nicht meine Antwort, in der ich mich auf das Vorkommen am Anfang und nicht in der Mitte bezog.

              Ich gehe aber davon aus, dass aus technischer Sicht gemeint war: der Aufruf der Funktion get_post_meta() soll einen String liefern/zurückgeben, der mit VRVR anfängt. Oder aus Anwendersicht: die Eingabe soll mit VRVR anfangen.

              Und selbst wenn stattdessen eine beliebige Position gewünscht war, so ist auch nicht dessen genaue Zahl interessant. Dann würde ein typsicherer Vergleich mit false auch in beiden Fällen die gewünschte Aussage treffen.


              Es gibt lediglich ein Problem wenn Zeichen in composed Form mit solchen in decomposed Form vergleichen werden sollen, aber das kann auch mb_strpos() nicht. Dazu müsste man vorher einen Normalizer (PECL, nicht überall installiert) drüberlaufen lassen, danach ist es aber auch wieder egal, ob man für "beginnt" oder "enthält" mb_strpos() oder strpos() nimmt.

              dedlfix.

              1. Da es nun vollkommen egal ist, wie die Anforderung lautet, würde ich einfach den weg wählen, der am einfachsten zu formulieren ist. Normalerweise steht halt irgendein Name in der Variablen und ich will nun eine einfach Variante finden, einen auf bestimmte Art und weise gekennzeichneten String erkennbar zu unterscheiden. Es muß halt irgendein String sein, den das tool, in dem eingetragen wird als Name frisst, also vermutlich nicht 00'sserwin2, wobei ich das nicht ausschliessen kann...jedoch lieber einfach einfach...

                Also am besten evtl: Wenn der String länger als 14 Zeichen ist...einfach ohne VRVR...noch einfacher und weniger Grundlage zur Diskussion: wenn die Zeichenkette länger als 14 ist...

                1. Hallo,

                  die Anforderung ...

                  Vielleicht beschreibst du jetzt einfach mal das Problem.
                  Bisher hast du offenbar stattdessen das beschrieben, was du als Problemlösung vermutest…

                  Gruß
                  Kalk

                  1. achso...nachdem ich schon einiges so lösen konnte, ist mir eigentlich klar, daß es so gehen müßte...sonst war halt die frage immer nur, ob sich ein eintrag in einer variablen befindet oder nicht und das konnte leicht abgefragt werden.

                    es geht darum, daß einem tool (openestate immotool) ein datensatz (openimmo xml) erzeugt wird. Wenn nun für die Immobilie eine virtuelle Tour vorhanden ist, dann soll ein div gesetzt werden. Das würde ich im Datensatz in der Art markieren können, daß zB eine Variable und ich habe halt diese 'kontaktperson_vorname" aus bestimmten Gründen ausgesucht eine bestimmte Form hat. Wenn nun also die Variable nicht einen beliebigen Namen beinhaltet, sondern zB vierzehnvierzehn (also länger als 14 Zeichen), dann würde das in dem div hinterlegte Vorschaubild auf eine URL www.domain.de/vierzehnvierzehn/index.php verlinken und in einem neuen Fenster öffnen...ist halt nur so, daß falls keine tour hinterlegbar ist, auch nicht irgendein leeres div da rumhängen soll, wie es gegenwärtig der Fall ist...genau das will ich erreichen und es ginge nun in einem letzten Schritt um diese Abfrage.

                    1. Tach!

                      Das würde ich im Datensatz in der Art markieren können, daß zB eine Variable und ich habe halt diese 'kontaktperson_vorname" aus bestimmten Gründen ausgesucht eine bestimmte Form hat.

                      Wie du sicher schon bemerkt hast, ist das keine besonders clevere Lösung. Aber gut, nehmen wir an, dass es keinen anderen Weg gibt.

                      Die Sache mit den 14 Zeichen wäre mit zu unsicher. Personennamen haben die Angewohnheit, zwischen ganz kurz und ganz lang zu sein. Mit lediglich 14 Zeichen mehr, ist keine konkrete Aussage zu treffen, ob das noch ein Personenname ist oder schon ein Personenname mit Zusatz. Da würde ich eher auf einen eindeutigen Zusatz prüfen wollen, beispielsweise %VR%. Prozentzeichen in Namen sind "eher selten", und somit eindeutig von Namensbestandteilen unterscheidbar. Andere Zeichen gehen auch. Müssen die URL-fest sein? (Eigentlich nicht, wenn es POST-Daten sind.) Dann wären auch Unterstriche möglich. Bindestriche kommen auch im Namen vor, aber wenn man auf "am Anfang" testen möchte, sollte das auch kein Problem sein.

                      <?php if (strpos(get_post_meta($post->ID, 'kontaktperson_vorname', true), '%VR%') === 0) : ?>
                      

                      So sähe das für "wenn am Anfang stehend, dann ..." aus, und es ist auch egal, ob in deinem System ISO-8859-1 oder UTF-8 verwendet wird. Wenn die Bedingung andersrum sein soll, dann !== statt === nehmen.

                      dedlfix.

                  2. Hello Tabellenkalk,

                    die Anforderung ...

                    Vielleicht beschreibst du jetzt einfach mal das Problem.
                    Bisher hast du offenbar stattdessen das beschrieben, was du als Problemlösung vermutest…

                    Du hast hier eine mMn weise Feststellung/Aussage getroffen. Die würde ich gerne in den "goldenen Regeln" des SelfRaumes (Forum und Wiki) verewigt sehen. Aber gibt es die überhaupt schon?

                    • Formuliere deine Fragen so, dass sie zunächst dein Problem
                    • dann das gwünschte Ziel (tritt dafür einen bis zwei Schritte zurück)
                    • dann deine bereits versuchten Lösungswege

                    beschreiben.

                    So, oder zumindest so ähnlich funktioniert Problemanalyse.

                    • reagiere positiv auf alle erhaltenen Antworten
                    • nutze die erhaltenen Anregungen dazu, deinen Denkbereich zunächst zu erweitern
                    • Filtere erst ganz am Ende die erhaltenen Informationen und bewerte sie

                    Glück Auf
                    Tom vom Berg

                    --
                    Es gibt nichts Gutes, außer man tut es!
                    Das Leben selbst ist der Sinn.
                2. Tach!

                  Da es nun vollkommen egal ist, wie die Anforderung lautet, würde ich einfach den weg wählen, der am einfachsten zu formulieren ist.

                  Naja, auf die Gefahr hin, übermäßig genau zu sein, das kann nicht egal sein, wenn du eine funktionierende Lösung haben möchtest. Entweder definierst du gegenüber den Anwendern (Anwenderfreundlichkeit mal nicht betrachtend): wenn Fall XY vorliegt, müsst ihr die Eingabe mit ABC beginnen lassen. Oder du lässt den Anwendern mehr Freiheiten und definierst exakt, unter welchen Bedingungen der Fall XY erkannt werden soll. "Exakt" heißt natürlich, dass du keine Variante vergessen darfst. Und die Varianten müssen gegeneinander eindeutig sein. Wenn sie sich widersprechen, ist daraus kein verwendbarer Algorithmus formulierbar.

                  Also am besten evtl: Wenn der String länger als 14 Zeichen ist...einfach ohne VRVR...noch einfacher und weniger Grundlage zur Diskussion: wenn die Zeichenkette länger als 14 ist...

                  Wenn die Länge das Kriterium sein soll, dann mb_strlen() mit Angabe der verwendeten Kodierung, denn bei UTF-8 (was man heutzutage einsetzen sollte) ist es ein Unterschied, ob man Bytes oder Zeichen zählt. Wenn das System lediglich mit ISO-8859-1 arbeitet, dann geht auch strlen().

                  dedlfix.

                  1. "unterstrichVRunterstrich*" geht astrein. Ja, muß URL fest sein. Da greifen tausend php Dateien ineinander und daher auch die Einschränkungen.

                    Super, super Lösung und absolut gut handzuhaben!! Tausend Dank!!!