diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd96c37 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/vendor/ +/src/log.txt +/test/myTestLogFile.txt +/test/log.txt \ No newline at end of file diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..76ef48d --- /dev/null +++ b/LICENCE @@ -0,0 +1,7 @@ +Copyright 2021 ArashAbedii + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 55cbd05..89625c0 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,80 @@ -# SERVER -## php class to work on different web services (API) +## A simple class for sending http requests +Send http requests and receive answers easily with a few lines by this class; This class is just a simple example that can be turned into a more professional software with your help -
+# How to use +In the first step, install the software package with composer (if you do not know what composer is, [click here](https://code.tutsplus.com/tutorials/what-is-composer-for-php-and-how-to-install-it--cms-35160 "click here")) -## usage +### Installation with Composer +Run this command on your command line (make sure composer is installed) +```bash +composer require arashabedii/server ``` -Server::sendRequest(string url, array parameters, string request type= get or post, array headers); +### Add depending on the application +Now by loading the autoload.php file created in the Vendor folder you will have access to the class. Create and use an object from the class +```php + 'Mhmmdq', + 'email' => 'mhmmdq@mhmmdq.ir', + 'github' => 'mhmmdq' +]; + +$request = new Server; +echo $request->sendRequest($url , $params , 'post'); ``` -

+### Submit a request +In general, to send a request to the server, you must use the `sendRequest` method, which accepts the following inputs: -#### at first include Server.php file to your project file
-``` -require 'Server.php'; -``` -#### after you can call Server::sendRequest() to send your requests. - -

- - ## examples: - -
- - **SEND GET REQUEST**
- ```PHP - 'cat','amount'=>5]; - $response=Server::sendRequest($url,$params,'GET'); - - echo '
';
-      var_dump(json_decode($response,true));
-      echo '
'; - - ``` -

+`$url` The first and only mandatory entry of the string in which the destination of the request is placed +`$params` An array in which the parameters sent to the destination are placed as keys and values ​​and can be empty -**SEND POST REQUEST**
-```PHP - '1','parameter2'=>2]; - $response=Server::sendRequest($url,$params,'POST'); - - echo '
';
-      var_dump(json_decode($response,true));
-      echo '
'; +`$headers` If you need to send a special header to the destination, you can enter it as a key and value array +```php +$request->sendRequest('https://mhmmdq.ir/requestTest.php' , [ + 'username'=>'mhmmdq' , + 'password'=>'xxxxxxxx'] , 'post'); ``` +#### Send a request directly with the get method +You can send your request directly using the get command -

- +```php +echo $request->get($url , $params); +``` -**SEND POST REQUEST WITH HEADERS**
+#### Send a request directly with the post method +You can send your request directly using the post command - ```PHP - post($url , $params); +``` - require 'Server.php'; +### Errors And Logs +If there is an error while performing a variable called `haveError` will be converted to `true` and the entire list of errors will be placed in a variable called `errors`. Also, all errors will be recorded in a file whose location and name can be changed. - //SEND POST REQUEST - $url="https://api.example.com/v1/method"; - $headers=['Authorization'=>'Bearer ACCESS_TOKEN']; - $params=[]; - //send request - $response=Server::sendRequest($url,[],$request_type,$headers); +```php +if($request->haveError) { + var_dump($request->errors); +} +``` - echo '
';
-      var_dump(json_decode($response,true));
-      echo '
'; +##### Specify the log file address +You can change the storage location of the file as shown below +```php +Server::changeLogPath(__DIR__ . 'log.txt'); +``` +### Move user to a new location +```php +$request->redirect('https://google.com'); ``` + diff --git a/Server.php b/Server.php deleted file mode 100644 index 36d3402..0000000 --- a/Server.php +++ /dev/null @@ -1,256 +0,0 @@ -$value){ - $value=str_replace(" ","%20",$value); - $output.=$key."=".$value."&"; - - } - - return "?".trim($output,"&"); //return GET format (?a=1&b=2&c=3) - - } - - - - private static function changeArrayToHeaderFormat($headers){ - - $output=array(); - - foreach($headers as $key=>$value){ - - $output[]="$key: $value"; - - } - - return $output; //return array of headers format (["Referer: https://www.google.com/","Content-type: audio/mpeg"]) - - } - - - - - - //CHECK VALIDATE INPUTS - - private static function validateUrl($url){ - - if(empty($url)){ - - file_put_contents("ErrHandler.log","\nERR MESSAGE: Url required !\t".date("d M Y H:i:s"),FILE_APPEND); - - self::$err=true; - - } - - if(!filter_var($url,FILTER_VALIDATE_URL)){ - - file_put_contents("ErrHandler.log","\nERR MESSAGE: Invalid url format !\t".date("d M Y H:i:s"),FILE_APPEND); - - self::$err=true; - - } - - } - - - - private static function validParams($params){ - - if(!is_array($params)){ - - file_put_contents("ErrHandler.log","\nERR MESSAGE: Invalid params format! params format should be an array\t".date("d M Y H:i:s"),FILE_APPEND); - - self::$err=true; - - } - - } - - - - private static function validHeaders($headers){ - - if(!is_array($headers)){ - - file_put_contents("ErrHandler.log","\nERR MESSAGE: Invalid headers format! headers format should be an array\t".date("d M Y H:i:s"),FILE_APPEND); - - self::$err=true; - - } - - } - - - - private static function validType($reqtype){ - - if(empty($reqtype)){ - - file_put_contents("ErrHandler.log","\nERR MESSAGE: Request type required! put GET or POST or etc type\t".date("d M Y H:i:s"),FILE_APPEND); - - self::$err=true; - - } - - } - - - - - - - -} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..1adc64a --- /dev/null +++ b/composer.json @@ -0,0 +1,28 @@ +{ + "name": "arashabedii/server", + "type": "library", + "description": "php class to work on different web services", + "license": "MIT", + "autoload": { + "psr-4": { + "ArashAbedii\\Server\\": "src/" + } + }, + "authors": [ + { + "name": "mhmmdq", + "email": "mhmmdq@mhmmdq.ir", + "homepage": "https://github.com/mhmmdq", + "role": "Developer" + }, + { + "name": "ArashAbedii", + "email": "arashabedi998@gmail.com", + "homepage": "https://arashabedi.com", + "role": "Developer" + } + ], + "require": { + "filp/whoops": "^2.14" + } +} diff --git a/src/Exception.php b/src/Exception.php new file mode 100644 index 0000000..51a3c4d --- /dev/null +++ b/src/Exception.php @@ -0,0 +1,8 @@ + + * @copyright Copyright (c), 2021 Mhmmdq + * @license MIT public license + */ + +namespace ArashAbedii\Server; + +class Logger { + /** + * We keep the log file storage location in this variable + * + * @var string + */ + protected static $file_path = 'log.txt'; + + /** + * Define the __construct method privately to prevent the class from being constructed as an object + * + */ + private function __construct() + { + + } + + /** + * Reload log file storage + * + * @param string $newPath + * @return void + */ + public static function changeLogPath($newPath) { + + self::$file_path = $newPath; + + } + + /** + * Save the log in the file + * + * @param string $text + * @return void + */ + protected static function saveLog($text) { + + # Using mode a causes a file to be created in the absence of a file + $file = fopen(self::$file_path , 'a'); + + + $date = date("F j, Y, g:i a"); + + # A simple structure to make the log file more beautiful + $string = "----------------- {$date} -----------------\n"; + $string .= "Error Mwssage: {$text}\n"; + $string .= "Timestamp: ".time()."\n"; + $string .= "----------------- {$date} -----------------\n\n\n"; + + # Write to file and exit the file + fwrite($file , $string); + fclose($file); + } + + + +} \ No newline at end of file diff --git a/src/Server.php b/src/Server.php new file mode 100644 index 0000000..fe3d7c3 --- /dev/null +++ b/src/Server.php @@ -0,0 +1,298 @@ + + * @author mhmmdq + * @copyright Copyright (c), 2021 ArashAbedii + * @license MIT public license + */ +namespace ArashAbedii\Server; + +class Server extends Logger{ + + /** + * If a problem occurs, the value changes to true + * + * @var boolean + */ + public $haveError = false; + + /** + * The target url for sending data and receiving output is in this variable + * + * @var string + */ + protected $url; + + /** + * The values ​​to be sent to the url are included in this array + * + * @var array + */ + protected $params = []; + + /** + * The method of sending values ​​to the url is included in this presentation + * + * @var string + */ + protected $method; + + /** + * Headers that need to be sent to the url are included in this presentation + * + * @var array + */ + protected $headers = []; + + /** + * curl is kept in this variable + * + * + */ + public $curlInit; + + /** + * Proxies are maintained for connection in this presentation + * + * @var array + */ + protected $proxy = []; + + /** + * All errors are stored in this variable + * + * @var array + */ + public $errors = []; + + public function __construct() + { + if (!extension_loaded('curl')) { + self::saveLog('cURL library is not loaded'); + throw new \Exception('cURL library is not loaded'); + } + + $this->curlInit = curl_init(); + } + + /** + * Send a request to the desired url + * + * @param string $url + * @param array $params + * @param string $type + * @param array $headers + * @param array $proxy + * @return string + */ + public function sendRequest(string $url, array $params = [], string $method = 'get', array $headers = [] , array $proxy = []) { + + # Check inputs + $this->checkInputs(['url' => $url , 'proxy' => $proxy]); + + if(!$this->haveError) { + + $this->url = $url; + $this->params = $params; + $this->method = strtoupper($method); + $this->headers = $headers; + $this->proxy = $proxy; + + return $this->createRequest()->exec(); + + } + } + /** + * Make a request ready to send + * + * + */ + protected function createRequest() { + + + + if($this->method == "GET") { + $this->url .= "?" . http_build_query($this->params); + } + + curl_setopt($this->curlInit , CURLOPT_URL , $this->url); + + if($this->method == "POST") { + $this->sendPostRequest(); + } + + if(!empty($this->headers)) { + $this->useCustomHeader(); + } + + if(!empty($this->proxy)) { + $this->connectProxyServer(); + } + + + + + curl_setopt($this->curlInit, CURLOPT_RETURNTRANSFER, true); + + return $this; + + } + /** + * If the method is post, the requirements apply + * + * @return void + */ + protected function sendPostRequest() { + + curl_setopt($this->curlInit , CURLOPT_POST , 1); + curl_setopt($this->curlInit , CURLOPT_POSTFIELDS , $this->params); + + } + + /** + * Headers apply if the user has a specific header to send + * + * @return void + */ + protected function useCustomHeader() { + + curl_setopt($this->curlInit , CURLOPT_HTTPHEADER , $this->headers); + + } + + /** + * Executes the output and returns the result + * + * @return string + */ + + public function exec() { + $responsve = curl_exec($this->curlInit); + + if($responsve !== false) + return $responsve; + else + $this->curlError(); + + curl_close($this->curlInit); + + } + /** + * Save curl problems in the list of errors + * + * @return void + */ + protected function curlError() { + $this->haveError = true; + $this->errors['curl_error'] = curl_error($this->curlInit); + self::saveLog('CURLERROR: ' . $this->errors['curl_error']); + + + } + + /** + * Examines the inputs + * + * @param array $inputs + * @return void + */ + protected function checkInputs(array $inputs) + { + + extract($inputs); + + if(!isset($url) && !filter_var($url , FILTER_VALIDATE_URL)) { + + $this->haveError = true; + $this->errors[] = 'A valid url is required'; + self::saveLog('A valid url is required'); + + } + + if(isset($proxy) && !empty($proxy)) { + + if(!filter_var($proxy['ip'] , FILTER_VALIDATE_IP)) { + $this->haveError = true; + $this->errors[] = 'You need a valid IP to connect to the proxy'; + self::saveLog('You need a valid IP to connect to the proxy'); + } + + if(!is_numeric($proxy['port'])) { + + $this->haveError = true; + $this->errors[] = 'The proxy port must be a number'; + self::saveLog('The proxy port must be a number'); + + } + + } + + + } + + /** + * A method for sending a direct request to Post + * + * @param string $url + * @param array $params + * @param array $headers + * @param array $proxy + * @return string + */ + public function post(string $url , array $params = [] , array $headers = [] , array $proxy = []) { + + return $this->sendRequest($url , $params , "POST" , $headers , $proxy); + + } + + /** + * A method for sending a direct request to get + * + * @param string $url + * @param array $params + * @param array $headers + * @param array $proxy + * @return string + */ + public function get(string $url , array $params = [] , array $headers = [] , array $proxy = []) { + + return $this->sendRequest($url , $params , "GET" , $headers , $proxy); + + } + /** + * Connect to the http proxy + * + * @return void + */ + public function connectProxyServer() { + + curl_setopt($this->curlInit, CURLOPT_PROXY, $this->proxy['ip']); + curl_setopt($this->curlInit, CURLOPT_PROXYPORT, $this->proxy['port']); + + if(isset($this->proxy['auth'])) { + + curl_setopt($this->curlInit, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + curl_setopt($this->curlInit, CURLOPT_PROXYUSERPWD, $this->proxy['auth']); + + } + + } + /** + * Move the user to a new page + * + * @param string $url + * @return void + */ + public function redirect(string $url) { + header('location: ' . $url); + } + + + + + + +} diff --git a/test.php b/test.php deleted file mode 100644 index 1d81501..0000000 --- a/test.php +++ /dev/null @@ -1,13 +0,0 @@ -'cat','amount'=>5]; -$response=Server::sendRequest($url,$params,'GET'); - -echo '
';
-var_dump(json_decode($response,true));
-echo '
'; diff --git a/test/LogTest.php b/test/LogTest.php new file mode 100644 index 0000000..3f13df8 --- /dev/null +++ b/test/LogTest.php @@ -0,0 +1,18 @@ + 'Mhmmdq', + 'email' => 'mhmmdq@mhmmdq.ir', + 'github' => 'mhmmdq' + ]; + + $request = new Server; + echo $request->sendRequest($url , $params , 'post'); + + + } +} + +RequestTest::test(); \ No newline at end of file