24

How to search text using php?

Something like:

<?php

$text = "Hello World!";

if ($text contains "World") {
    echo "True";
}

?>

Except replacing if ($text contains "World") { with a working condition.

Ethan
  • 4,295
  • 4
  • 25
  • 44
faressoft
  • 19,053
  • 44
  • 104
  • 146
  • You might find [`s($str)->contains('World')`](https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/Str.php#L93) and [`s($str)->containsIgnoreCase('World')`](https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/Str.php#L105) helpful, as found in [this standalone library](https://github.com/delight-im/PHP-Str). – caw Jul 27 '16 at 01:19

7 Answers7

45

In your case you can just use strpos(), or stripos() for case insensitive search:

if (stripos($text, "world") !== false) {
    echo "True";
}
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
10

What you need is strstr()(or stristr(), like LucaB pointed out). Use it like this:

if(strstr($text, "world")) {/* do stuff */}
Gabi Purcaru
  • 30,940
  • 9
  • 79
  • 95
  • 4
    strpos or stripos is better for the use case given by the OP - strstr goes to all the trouble of constructing a new string, only to be thrown away... – Paul Dixon Oct 16 '10 at 20:30
  • 1
    Adding to Paul's comment, from the PHP manual for [`strstr()`](http://www.php.net/manual/en/function.strstr.php): "If you only want to determine if a particular needle occurs within haystack, use the faster and less memory intensive function `strpos()` instead." – BoltClock Oct 16 '10 at 20:35
  • Well actually, it's an unreasonable microoptimization to use strpos over strstr given the original example. The returned string goes to waste, but basing the decision on 'performance' for a *single* text search doesn't seem sensible. – mario Oct 16 '10 at 21:14
  • So why are you arguing over it one way or the other, @mario! Seems like a waste of time.... ;-) – Peter K. Oct 07 '15 at 16:49
6

If you are looking an algorithm to rank search results based on relevance of multiple words here comes a quick and easy way of generating search results with PHP only.

Implementation of the vector space model in PHP

function get_corpus_index($corpus = array(), $separator=' ') {

    $dictionary = array();
    $doc_count = array();

    foreach($corpus as $doc_id => $doc) {
        $terms = explode($separator, $doc);
        $doc_count[$doc_id] = count($terms);

        // tf–idf, short for term frequency–inverse document frequency, 
        // according to wikipedia is a numerical statistic that is intended to reflect 
        // how important a word is to a document in a corpus

        foreach($terms as $term) {
            if(!isset($dictionary[$term])) {
                $dictionary[$term] = array('document_frequency' => 0, 'postings' => array());
            }
            if(!isset($dictionary[$term]['postings'][$doc_id])) {
                $dictionary[$term]['document_frequency']++;
                $dictionary[$term]['postings'][$doc_id] = array('term_frequency' => 0);
            }

            $dictionary[$term]['postings'][$doc_id]['term_frequency']++;
        }

        //from http://phpir.com/simple-search-the-vector-space-model/

    }

    return array('doc_count' => $doc_count, 'dictionary' => $dictionary);
}

function get_similar_documents($query='', $corpus=array(), $separator=' '){

    $similar_documents=array();

    if($query!=''&&!empty($corpus)){

        $words=explode($separator,$query);
        $corpus=get_corpus_index($corpus);
        $doc_count=count($corpus['doc_count']);

        foreach($words as $word) {
            $entry = $corpus['dictionary'][$word];
            foreach($entry['postings'] as $doc_id => $posting) {

                //get term frequency–inverse document frequency
                $score=$posting['term_frequency'] * log($doc_count + 1 / $entry['document_frequency'] + 1, 2);

                if(isset($similar_documents[$doc_id])){
                    $similar_documents[$doc_id]+=$score;
                }
                else{
                    $similar_documents[$doc_id]=$score;
                }

            }
        }

        // length normalise
        foreach($similar_documents as $doc_id => $score) {
            $similar_documents[$doc_id] = $score/$corpus['doc_count'][$doc_id];
        }

        // sort fro  high to low
        arsort($similar_documents);
    }   
    return $similar_documents;
}

IN YOUR CASE

$query = 'world';

$corpus = array(
    1 => 'hello world',
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';

RESULTS

Array
(
    [1] => 0.79248125036058
)

MATCHING MULTIPLE WORDS AGAINST MULTIPLE PHRASES

$query = 'hello world';

$corpus = array(
    1 => 'hello world how are you today?',
    2 => 'how do you do world',
    3 => 'hello, here you are! how are you? Are we done yet?'
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';

RESULTS

Array
(
    [1] => 0.74864218272161
    [2] => 0.43398500028846
)

from How do I check if a string contains a specific word in PHP?

Community
  • 1
  • 1
RafaSashi
  • 16,483
  • 8
  • 84
  • 94
  • Why was the last line (3) of the array not evaluated? It starts with "hello" but was not displayed in the final result – Guttemberg Aug 25 '19 at 14:51
2

This might be what you are looking for:

<?php

$text = 'This is a Simple text.';

// this echoes "is is a Simple text." because 'i' is matched first
echo strpbrk($text, 'mi');

// this echoes "Simple text." because chars are case sensitive
echo strpbrk($text, 'S');
?>

Is it?

Or maybe this:

<?php
$mystring = 'abc';
$findme   = 'a';
$pos = strpos($mystring, $findme);

// Note our use of ===.  Simply == would not work as expected
// because the position of 'a' was the 0th (first) character.
if ($pos === false) {
    echo "The string '$findme' was not found in the string '$mystring'";
} else {
    echo "The string '$findme' was found in the string '$mystring'";
    echo " and exists at position $pos";
}
?>

Or even this

<?php
$email  = 'name@example.com';
$domain = strstr($email, '@');
echo $domain; // prints @example.com

$user = strstr($email, '@', true); // As of PHP 5.3.0
echo $user; // prints name
?>

You can read all about them in the documentation here:

http://php.net/manual/en/book.strings.php

Trufa
  • 39,971
  • 43
  • 126
  • 190
1

in my opinion strstr() is better than strpos(). because strstr() is compatible with both PHP 4 AND PHP 5. but strpos() is only compatible with PHP 5. please note that part of servers have no PHP 5

Mahdi Jazini
  • 791
  • 9
  • 16
  • 2
    Uhm - PHP5 was first released in 2004. If compatibility with PHP4 is really an issue, I suggest you change to a different hosting company. – Edward Jan 12 '15 at 10:24
0
  /* https://ideone.com/saBPIe */

  function search($search, $string) {

    $pos = strpos($string, $search);  

    if ($pos === false) {

      return "not found";     

    } else {

      return "found in " . $pos;

    }    

  }

  echo search("world", "hello world");

Embed PHP online:

body, html, iframe { 
  width: 100% ;
  height: 100% ;
  overflow: hidden ;
}
<iframe src="https://ideone.com/saBPIe" ></iframe>
antelove
  • 3,216
  • 26
  • 20
0

The best solution is my method:

In my method, only full words are detected,But in other ways it is not.

for example:

$text='hello world!'; 

if(strpos($text, 'wor') === FALSE) { 
   echo '"wor" not found in string'; 
}

Result: strpos returned true!!! but in my method return false.

My method:

public function searchInLine($txt,$word){

    $txt=strtolower($txt);
    $word=strtolower($word);
    $word_length=strlen($word);
    $string_length=strlen($txt);
    if(strpos($txt,$word)!==false){
        $indx=strpos($txt,$word);
        $last_word=$indx+$word_length;
        if($indx==0){
            if(strpos($txt,$word." ")!==false){
                return true;
            }
            if(strpos($txt,$word.".")!==false){
                return true;
            }
            if(strpos($txt,$word.",")!==false){
                return true;
            }
            if(strpos($txt,$word."?")!==false){
                return true;
            }
            if(strpos($txt,$word."!")!==false){
                return true;
            }
        }else if($last_word==$string_length){
            if(strpos($txt," ".$word)!==false){
                return true;
            }
            if(strpos($txt,".".$word)!==false){
                return true;
            }
            if(strpos($txt,",".$word)!==false){
                return true;
            }
            if(strpos($txt,"?".$word)!==false){
                return true;
            }
            if(strpos($txt,"!".$word)!==false){
                return true;
            }

        }else{
            if(strpos($txt," ".$word." ")!==false){
                return true;
            }
            if(strpos($txt," ".$word.".")!==false){
                return true;
            }
            if(strpos($txt," ".$word.",")!==false){
                return true;
            }
            if(strpos($txt," ".$word."!")!==false){
                return true;
            }
            if(strpos($txt," ".$word."?")!==false){
                return true;
            }
        }
        }

    return false;
}
Skatox
  • 4,237
  • 12
  • 42
  • 47
M.ghorbani
  • 129
  • 8
  • Can you explain how your method beats the builtin strpos or what advantages it gives? – user1781290 Aug 27 '19 at 08:55
  • In my method, only full words are detected,But in other ways it is not.for example: $text='hello world!'; if(strpos($text, 'wor') === FALSE) { echo '"wor" not found in string'; } result: strpos returned true!!! but in my method return false. – M.ghorbani Aug 27 '19 at 09:29
  • Thank you; I'd suggest adding what you commented to your answer in order to make this clearer – user1781290 Aug 27 '19 at 09:42