Skip to content

Instantly share code, notes, and snippets.

@balwantmeticulosity
Created March 24, 2021 05:34
Show Gist options
  • Select an option

  • Save balwantmeticulosity/2e471821838fd725c93abbcee583c23d to your computer and use it in GitHub Desktop.

Select an option

Save balwantmeticulosity/2e471821838fd725c93abbcee583c23d to your computer and use it in GitHub Desktop.
Get Google-Reviews with PHP cURL & without API Key
<?php
/*
💬 Get Google-Reviews with PHP cURL & without API Key
=====================================================
**This is a dirty but usefull way to grab the first 8 most relevant reviews from Google with cURL and without the use of an API Key**
How to find the needed CID No:
- use: [https://pleper.com/index.php?do=tools&sdo=cid_converter]
- and do a search for your business name
Parameter
---------
```PHP
$options = array(
'google_maps_review_cid' => '17311646584374698221', // Customer Identification (CID)
'show_only_if_with_text' => false, // true = show only reviews that have text
'show_only_if_greater_x' => 0, // (0-4) only show reviews with more than x stars
'show_rule_after_review' => true, // false = don't show <hr> Tag after each review
'show_blank_star_till_5' => true, // false = don't show always 5 stars e.g. ⭐⭐⭐☆☆
'your_language_for_tran' => 'en', // give you language for auto translate reviews
'sort_by_reating_best_1' => true, // true = sort by rating (best first)
'show_cname_as_headline' => true, // true = show customer name as headline
'show_age_of_the_review' => true, // true = show the age of each review
'show_txt_of_the_review' => true, // true = show the text of each review
'show_author_of_reviews' => true, // true = show the author of each review
);
echo getReviews($options);
```
> HINT: Use .quote in you CSS to style the output
###### Copyright 2019-2020 Igor Gaffling
*/
$options = array(
'google_maps_review_cid' => '10054689419972994821', // Customer Identification (CID)
'show_only_if_with_text' => false, // true = show only reviews that have text
'show_only_if_greater_x' => 0, // (0-4) only show reviews with more than x stars
'show_rule_after_review' => true, // false = don't show <hr> Tag after each review (and before first)
'show_blank_star_till_5' => true, // false = don't show always 5 stars e.g. ⭐⭐⭐☆☆
'your_language_for_tran' => 'en', // give you language for auto translate reviews
'sort_by_reating_best_1' => true, // true = sort by rating (best first)
'show_cname_as_headline' => true, // true = show customer name as headline
'show_age_of_the_review' => true, // true = show the age of each review
'show_txt_of_the_review' => true, // true = show the text of each review
'show_author_of_reviews' => true, // true = show the author of each review
);
/* -------------------- */
echo getReviews($options);
/* -------------------- */
function getReviews($option) {
$ch = curl_init('https://www.google.com/maps?cid='.$option['google_maps_review_cid']); /* GOOGLE REVIEWS BY cURL */
if ( isset($option['your_language_for_tran']) and !empty($option['your_language_for_tran']) ) {
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Language: '.$option['your_language_for_tran']));
}
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch); /* </cURL END> */
$pattern = '/window\.APP_INITIALIZATION_STATE(.*);window\.APP_FLAGS=/ms'; /* REVIEW REGEX PATTERN */
if ( preg_match($pattern, $result, $match) ) { /* CHECK IF REVIEWS FOUND */
$match[1] = trim($match[1], ' =;'); /* DIRTY JSON FIX */
$reviews = json_decode($match[1]); /* 2. JSON DECODE */
$reviews = ltrim($reviews[3][6], ")]}'"); /* DIRTY JSON FIX */
$reviews = json_decode($reviews); /* 2. JSON DECODE */
$customer = $reviews[6][11]; /* POSITION OF REVIEWS */
$reviews = $reviews[6][52][0]; /* POSITION OF REVIEWS */
} /* END CHECK */
$return = ''; /* INI VAR */
if (isset($reviews)) { /* CHECK REVIEWS */
if ( isset($option['sort_by_reating_best_1']) and $option['your_lansort_by_reating_best_1guage_for_tran'] == true ) /* CHECK SORT */
array_multisort(array_map(function($element) { return $element[4]; }, $reviews), SORT_DESC, $reviews); /* SORT */
$return .= '<div class="quote">'; /* OPEN DIV */
if (isset($option['show_cname_as_headline']) and $option['show_cname_as_headline'] == true) $return .= '<strong>'.$customer.'</strong><br>'; /* CUSTOMER */
if (isset($option['show_rule_after_review']) and $option['show_rule_after_review'] == true) $return .= '<hr size="1">'; /* RULER */
foreach ($reviews as $review) { /* START LOOP */
if (isset($option['show_only_if_with_text']) and $option['show_only_if_with_text'] == true and empty($review[3])) continue; /* CHECK TEXT */
if (isset($option['show_only_if_greater_x']) and $review[4] <= $option['show_only_if_greater_x']) continue; /* CHECK RATING */
for ($i=1; $i <= $review[4]; ++$i) $return .= '⭐'; /* RATING */
if (isset($option['show_blank_star_till_5']) and $option['show_blank_star_till_5'] == true) for ($i=1; $i <= 5-$review[4]; ++$i) $return .= '☆'; /* RATING */
$return .= '<br>'; /* NEWLINE */
if (isset($option['show_txt_of_the_review']) and $option['show_txt_of_the_review'] == true) $return .= $review[3].'<br>'; /* TEXT */
if (isset($option['show_age_of_the_review']) and $option['show_age_of_the_review'] == true) $return .= '<small>'.$review[0][1].' </small>'; /* AUTHOR */
if (isset($option['show_age_of_the_review']) and $option['show_age_of_the_review'] == true and /* IF AUTHOR & AGE */
isset($option['show_age_of_the_review']) and $option['show_age_of_the_review'] == true) $return .= '<small> &mdash; </small>'; /* PRINT — */
if (isset($option['show_age_of_the_review']) and $option['show_age_of_the_review'] == true) $return .= '<small>'.$review[1].' </small>'; /* AGE */
if (isset($option['show_rule_after_review']) and $option['show_rule_after_review'] == true) $return .= '<hr size="1">'; /* RULER */
} /* END LOOP */
$return .= '</div>'; /* CLOSE DIV */
} /* CHECK REVIEWS */
return $return; /* RETURN DATA */
} /* END OF FUNCTION */
@tynafura
Copy link

Hi dear!

How can I ignore auto translate?
how can I get more reviews by date and earlies!

thanks
TY

@huurmanf
Copy link

Great script too bad it only works for a few days. How is that possible?

@huurmanf
Copy link

Google moved the URL. You have to put &ucbcb=1 after the CID.

@Dge-06
Copy link

Dge-06 commented Jul 29, 2022

Good !!!

how to filter from newest to oldest please?

Thanks

@iburunat
Copy link

Indeed, it stopped working for me after a few days. Is there a specific reason?

@divz90
Copy link

divz90 commented Mar 1, 2024

yesterday my code also stopped working. Anyone know what is the reason for that?

@kakitzmiller
Copy link

@divz90 I was looking through the results array and it looks like its location (and the edit to line 74) is now:

$reviews = $reviews[6][175][9][0][0];

Hope that helps!

@iburunat
Copy link

Thanks, @kakitzmiller ! before it was showing an empty page, not after your suggestion, it shows the name of the business (but nothing else, no reviews to be seen). Just reporting on my end. Do you get the reviews?

@cladreams
Copy link

Anyone in Aug 2024
Looks like the returned array has completely changed location trying to work on fixing it, anyone else had any luck?

@iburunat
Copy link

Anyone in Aug 2024 Looks like the returned array has completely changed location trying to work on fixing it, anyone else had any luck?

No luck sofar :( Keep us updated!

@cladreams
Copy link

Hello, I have got it to work again

Have to first change:

//$customer = $reviews[0][1][0][14][18];
//$reviews = $reviews[0][1][0][14][52][0];
//$customer = $reviews[6][18]; // NEW IN 2020
//$reviews = $reviews[6][52][0]; // NEW IN 2020
$customer = $reviews[6][175][9]; // NEW IN 2024
$reviews = $reviews[6][175][9][0][0]; // NEW IN 2024

Then inside the loop also change these 3 lines:

$comment_name=$review[0][1][4][5][0]; // NEW IN 2024
$review_text=$review[0][2][15][0][0]; // NEW IN 2024
$comment_rating=$review[0][2][0][0]; // NEW IN 2024

Let me know if it works for you :)

@iburunat
Copy link

Thanks for your help! It seems the changes aren’t working on my end—perhaps I’m not applying them correctly. Would it be possible to copy and paste the complete code here to ensure I’m inserting it correctly?

@divz90
Copy link

divz90 commented Aug 16, 2024

Thank you for ur replay. Its working for me also.

@CCX687
Copy link

CCX687 commented Aug 30, 2024

hello @cladreams, please copy and paste the complete code here

@cladreams
Copy link

Hello, currently moving house so no access to computer but I'll upload next week

@iburunat
Copy link

Thanks, buddy, I really appreciate it, since it's not working on my end.

@CCX687
Copy link

CCX687 commented Aug 31, 2024

Thanks @cladreams

@CCX687
Copy link

CCX687 commented Sep 4, 2024

@klebinhopk
Copy link

My code in 2024

<?php
    /*Get Google-Reviews with PHP cURL & without API Key
    =====================================================
    - use: [https://pleper.com/index.php?do=tools&sdo=cid_converter]
    */

    $options = array(
        'google_maps_review_cid' => 'YOUR-CID',
        'show_only_if_with_text' => false,
        'show_only_if_greater_x' => 0,
        'show_rule_after_review' => true,
        'show_blank_star_till_5' => true,
        'your_language_for_tran' => 'pt-BR',
        'sort_by_reating_best_1' => true,
        'show_cname_as_headline' => true,
        'show_age_of_the_review' => true,
        'show_txt_of_the_review' => true,
        'show_author_of_reviews' => true,
    );

    function getReviews($option, $CID = '')
    {
        if(isset($CID) && $CID !== ''){
            $option['google_maps_review_cid'] = $CID;
        }

        $ch = curl_init('https://www.google.com/maps?cid=' . ($option['google_maps_review_cid']));
        if (isset($option['your_language_for_tran']) and !empty($option['your_language_for_tran'])) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Language: ' . $option['your_language_for_tran']));
        }
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $result = curl_exec($ch);
        curl_close($ch);
        $pattern = '/window\.APP_INITIALIZATION_STATE(.*);window\.APP_FLAGS=/ms';
        if (preg_match($pattern, $result, $match)) {
            $match[1] = trim($match[1], ' =;');
            $reviews  = json_decode($match[1]);
            $reviews  = ltrim($reviews[3][6], ")]}'");
            $reviews  = json_decode($reviews);
            $customer = $reviews[6][11];
            $reviews  = $reviews[6][175][9][0][0];
        }
        
        $return = '';

        if (isset($reviews)) {
            if (isset($option['sort_by_reating_best_1'])) {
                usort($reviews, function ($a, $b) {
                    // Replace 'date' with the exact path or index where the timestamp is stored in the review array
                    $dateA = strtotime($a[0][1][6]); // Example: change this path to match your structure
                    $dateB = strtotime($b[0][1][6]);
                    return $dateB <=> $dateA; // Sorts in descending order
                });
                
                $return .= '<div class="reviews">';
                foreach ($reviews as $review) {
                    //$nome = $review[0][1][4][1][1]; //nao funciona mais
                    // print_r($review[0][1][4][5][0]);exit;
                    $nome = $review[0][1][4][5][0];
                    //$imagem = $review[0][1][4][1][2]; //nao funciona mais
                    // print_r($review[0][1][4][5][1]);exit;
                    $imagem = $review[0][1][4][5][1];
                    $estrelas = $review[0][2][0][0];
                    $descricao = isset($review[0][2][15][0][0]) ? resumirDescricao($review[0][2][15][0][0]) : 'Sem descrição';
                    $dataAvaliacao = $review[0][1][6];
            
                    // Exibição dos dados
                    $return .= '<div class="item border text-center mx-3 p-2 d-flex align-items-center flex-column justify-content-between" style="min-height:300px">';
                    $return .= "<img src=\"$imagem\" class=\"mb-2\" style=\"width:50px\"/>";
                    $return .= '<h3 class="fs-6">'.$nome.'</h3>';
                    $return .= '<div class="my-3">' . str_repeat('⭐', $estrelas) . str_repeat('☆', 5 - $estrelas) . '</div>';
                    $return .= "<p class=\"fs-6\"><small>$descricao</small></p>";
                    $return .= "<small class=\"bg-light border p-1 rounded-pill px-4\" style=\"font-size:12px;\">$dataAvaliacao</small>";
                    $return .= '</div>';
                }
            
            }
            $return .= '</div>';
        }
        return $return;
    }

    function resumirDescricao($descricao, $limitePalavras = 10) {
        $palavras = explode(' ', $descricao);
    
        if (count($palavras) > $limitePalavras) {
            $descricaoCurtada = implode(' ', array_slice($palavras, 0, $limitePalavras)) . '...';
        } else {
            $descricaoCurtada = $descricao;
        }
    
        return $descricaoCurtada;
    }
?>

Any suggestions for ordering the comments, returning the newest to the oldest. this doesn't work in my current code.

@manudj195
Copy link

in 2025 the url return "302 Moved"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment