1

Without class, just plain code my method is working and getting "SUCCESS" response_status, but when i put it in a class i get nothing.

All code:


class THBS_API
{
    private const call_url = "https://xxxxxxxxxxxx.xxx/endsoftware.php";
    private $base_url;
    private $fields;
    private $fields_string;

    public static function getUsers()
    {
        $base_url = $_SERVER['SERVER_NAME'];
        $fields_string = '';

        $fields = array(
        'API_USER' => urlencode('xxxxxx@xxxxxx.xxx'),
        'API_PASS' => urlencode('xxxxxxxxx'),
        'CMD' => urlencode('getUserCount'),
        'FROM' => urlencode($base_url));

        //url-ify the data for the POST
        foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
        rtrim($fields_string, '&');

        //open connection
        $ch = curl_init();

        //set the url, number of POST vars, POST data
        curl_setopt($ch,CURLOPT_URL, $call_url);
        curl_setopt($ch,CURLOPT_POST, count($fields));
        curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);


        //execute post
        $result = curl_exec($ch);

        //close connection
        curl_close($ch);

        $response = json_decode($result, true);
        return $response['response_status'];
    }
}



echo THBS_API::getUsers();

Is very weird, but i think is because declaring variables is different in classes, is the problem i use privar $base_url? and how to solve this?

P.S: that is my first class ever, i worked fine with normal functions, but i still want to learn classes functions

Now i get

Notice: Undefined variable: fields_string in /srv/disk1/3203065/www/xxxxxxxxxxxxxxxxxx.com/API/clientapi.php on line 24

Line 44:

return $response['response_status'];

Code without class (working):

$base_url = $_SERVER['SERVER_NAME'];
  $url = "https://xxxxxxxxxxx.com/API/endsoftware.php";


  $fields = array(
    'API_USER' => urlencode('xxxxxx@xxxxx.xxxx'),
    'API_PASS' => urlencode('xxxxxxxxxx'),
    'CMD' => urlencode('getUserCount'));

//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, '&');

//open connection
$ch = curl_init();

//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);


//execute post
$result = curl_exec($ch);

//close connection
curl_close($ch);

$response = json_decode($result, true);
echo $response['response_status'];

(returns "SUCCESS")

Thos-Host
  • 67
  • 9
  • Where is `$call_url` defined n your code? Maybe that is some global variable(hence it worked without the class)? – nice_dev Feb 07 '20 at 13:39
  • That was a mistake, i changed $url to $call_url but same. (edit thread imediately) – Thos-Host Feb 07 '20 at 13:40
  • 1
    Change `$call_url` to `$this->call_url` and see. – nice_dev Feb 07 '20 at 13:41
  • Also, since `call_url` doesn't seem to change, you can declare it as constant. – nice_dev Feb 07 '20 at 13:42
  • like this `define($call_url, "https://xxxxxxxxxxxxxxxx.com/endsoftware.php");`? @vivek_23 – Thos-Host Feb 07 '20 at 13:46
  • No, like `private const call_url = 'https://thos-host.com/endsoftware.php';` and you will access it like `self::call_url` – nice_dev Feb 07 '20 at 13:47
  • _“that is my first class ever, i worked fine with normal functions, but i still want to learn classes functions”_ - then you should at least go and read up on the _basics_ on your own! https://www.php.net/manual/en/language.oop5.properties.php explains how to access properties. – 04FS Feb 07 '20 at 13:50
  • ```namespace THBS_API; class THBS_API { private const $call_url = "https://thos-host.com/endsoftware.php"; <----- LINE 7 private $base_url; public static function getUsers() { $base_url = $_SERVER['SERVER_NAME'];...............``` I get > syntax error, unexpected '$call_url' (T_VARIABLE) in .... (at line 7) – Thos-Host Feb 07 '20 at 13:50
  • And please go and enable proper PHP error reporting! PHP would have already told you that you are trying to access variables that don’t exist in the current scope. – 04FS Feb 07 '20 at 13:51
  • @Thos-Host Remove the `$` from `$call_url`. – nice_dev Feb 07 '20 at 13:52
  • Undefined variable: fields_string in... foreach($fields as $key=>$value)....." – Thos-Host Feb 07 '20 at 13:54
  • @Thos-Host Whatever you are doing, you will have to show us by editing your post. These comments does not give us any hint. – nice_dev Feb 07 '20 at 13:56
  • okay, i edit now – Thos-Host Feb 07 '20 at 13:56
  • @Thos-Host Also check whether URL is actually the issue in not getting the response when added in class. – nice_dev Feb 07 '20 at 13:57
  • 1
    Define *$field_string* variable in top of you *getUsers* function like `$field_string = ''` then start concatenating it. – udit rawat Feb 07 '20 at 13:57
  • @vivek_23, i tried to make this in plain code, without class and has worked. – Thos-Host Feb 07 '20 at 14:00
  • Problem with field string solved – Thos-Host Feb 07 '20 at 14:00
  • @Thos-Host Share the working code. – nice_dev Feb 07 '20 at 14:02
  • @Thos-Host Check if this works for you https://pastebin.com/Tuv2KgmL – nice_dev Feb 07 '20 at 14:08
  • Working, thanks, please add it in an answer to give you solving badge @vivek_23. :) – Thos-Host Feb 07 '20 at 14:10

1 Answers1

0

A couple of changes to your code.

  • Since call_url is always going to be constant, you can declare it as a constant in your class.

  • Second is your are concatenating $field values one by one with an & which is not needed. You can use http_build_query function for this.

  • Third is you had curl_setopt($ch,CURLOPT_POST, count($fields)); which is incorrect since this says make a POST request only if we have more than 0 fields. You would want to make a proper request regardless of it. So, set it to true always.

Snippet:

<?php

namespace THBS_API;

class THBS_API{
    private const call_url = "https://xxxxxxxxxxx.com/API/endsoftware.php";

    public static function getUsers(){
        $base_url = $_SERVER['SERVER_NAME'];
        $fields = array(
            'API_USER' => urlencode('xxxxxx@xxxxxx.xxx'),
            'API_PASS' => urlencode('xxxxxxxxx'),
            'CMD' => urlencode('getUserCount'),
            'FROM' => urlencode($base_url)
        );

        //open connection
        $ch = curl_init();

        //set the url, number of POST vars, POST data
        curl_setopt($ch,CURLOPT_URL, self::call_url);
        curl_setopt($ch,CURLOPT_POST, true);
        curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($fields));
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); // add certificates once you have them(recommended)
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        //execute post
        $result = curl_exec($ch);

        //close connection
        curl_close($ch);

        $response = json_decode($result, true);
        return $response['response_status'];
    }
}


echo THBS_API::getUsers();

Update:

As @Dharman mentioned in the comments, you should always add certificates to your cURL requests to avoid man in the middle attacks attacks and this answer shows how you can add one to your cURL request.

Also, you can simply use http_build_query instead of individually encoding each one as http_build_query would do it anyway. So take off the urlencode from the above code.

nice_dev
  • 17,053
  • 2
  • 21
  • 35
  • Oh, and one last question: i made the function to have parameters and changed a little bit (working) How can i use arrow functions for classes functions? Like `$command->THBS_API::CMD_EXTERNAL();` – Thos-Host Feb 07 '20 at 14:22
  • $command is definied by $command = "getUserCount" (can be something like getTheme or anything i defined in my external API) – Thos-Host Feb 07 '20 at 14:25
  • simply i want to use `$command->THBS_API::CMD_EXTERNAL();` instead of `THBS_API::CMD_EXTERNAL($command);` – Thos-Host Feb 07 '20 at 14:25
  • @Thos-Host Ok, not very clear to me, but you can't do `$command->THBS_API::CMD_EXTERNAL();`. We use the `->` syntax in PHP only when we have an object with us and calling a class method with it. – nice_dev Feb 07 '20 at 14:27
  • 1
    **[You should not switch off `CURLOPT_SSL_VERIFYHOST` or `CURLOPT_SSL_VERIFYPEER`](https://paragonie.com/blog/2017/10/certainty-automated-cacert-pem-management-for-php-software)**. It could be a security risk! [Here is how to get the certificate bundle if your server is missing one](https://stackoverflow.com/a/32095378/1839439) – Dharman Feb 08 '20 at 17:46
  • @Dharman yes, that's why there is a comment saying you should attach a cert. – nice_dev Feb 08 '20 at 17:50
  • Why did you switch it off? I don't see these two lines in the question. – Dharman Feb 08 '20 at 17:51
  • @Dharman just in case OP doesn't get a response anymore, because his API site had https. – nice_dev Feb 08 '20 at 17:52
  • So just in case you suggested a way to introduce a vulnerability. What if OP already has a working certificate bundle? – Dharman Feb 08 '20 at 17:53
  • Also I see you are double encoding the parameters. First with `urlencode` and then with `http_build_query` – Dharman Feb 08 '20 at 17:53
  • @Dharman Well, I didn't see that in his post, so how should I be sure about it? – nice_dev Feb 08 '20 at 17:54
  • 1
    My point is don't tell someone how to do a bad thing, just because you might think they would ever need this poor workaround. If you suspect they might have an issue with SSL then tell them how to fix it. – Dharman Feb 08 '20 at 17:55
  • @Dharman Fair enough. I will update my answer with those cert related links. – nice_dev Feb 08 '20 at 17:58
  • @Thos-Host Please look at the update as it is very useful security wise as pointed out by Dharman. – nice_dev Feb 08 '20 at 18:27