I'm trying to generate an object of class Bar from POST data. I'm doing this using a function that I found here.
I post data from foo.php to bar.php.
bar.php successfully receives the post data and runs the static method Bar::generate, which returns a Bar object.
The problem is, even though the function receives the correct data and knows where to set it, the returned objects properties are empty.
foo.php
<?php
function postArray($array, $destScript){
try {
$ch = curl_init();
if (FALSE === $ch){
throw new Exception('failed to initialize');
}
curl_setopt($ch, CURLOPT_URL,$destScript);
curl_setopt($ch, CURLOPT_POST, count($array));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$content = curl_exec($ch);
return $content;
if (FALSE === $content)
throw new Exception(curl_error($ch), curl_errno($ch));
} catch(Exception $e) {
trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()),E_USER_ERROR);
}
}
echo postArray(array('action' => 'generate', 'first' => 'yes', 'second' => 'no', 'third' => 'maybe'), 'http://herbie.eu/indev/bar.php');
?>
bar.php
<?php
class Bar{
public $first;
public $second;
public $third;
private function __construct($options){
$this->loadFromArray($options);
}
private function loadFromArray($array) {
$class = new ReflectionClass(get_class($this));
$props = $class->getProperties();
foreach($props as $p) {
if (isset($array[$p->getName()])){
$p->setValue($this, $array[$p->getName]);
echo $p->getName()." = ".$array[$p->getName()]."<br>";
}
}
echo "<br>";
}
static public function generate($options){
try{
return new Bar($options);
}
catch(NotFoundException $unfe){
echo 'Bar::generate failed + '.$unfe;
return NULL;
}
}
}
if(!empty($_POST['action'])){
if($_POST['action'] == "generate"){
$booking = Bar::generate($_POST);
echo "success ".count($_POST)."<br>";
print_r($booking);
}
}
else{
echo "WARNING_L0: ${_POST}['action'] not set";
}
?>
Running foo.php returns,
first = yes
second = no
third = maybe
success 4
Bar Object ( [first] => [second] => [third] => )
As you can see, the ReflectionClass in loadFromArray knows exactly what to put where, but the returned object is empty. The 4 is the result of count($_POST).
Related
I learn MVC recently. I try to rebulid my website in MVC structure, and i have a problem to call function inside different name sapace(maybe i don't know about OOP very much). Here is my code:
namespace UserFrosting;
class GroupController extends \UserFrosting\BaseController {
public function testFunction($params){
//Simple test function that i had error: Call to undefined function UserFrosting\testFunction()
$params['Password'] = $pw;
$params['JSON'] = 'Yes';
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($curl);
if (curl_errno($curl)) $obj = (object) array('Result' => 'Error', 'Error' => curl_error($curl));
else if (empty($response)) $obj = (object) array('Result' => 'Error', 'Error' => 'Connection failed');
else $obj = json_decode($response);
curl_close($curl);
return $obj;
}
public function loginNumber(){
$params = array("Command" => "SystemStats");
$api = testFunction($params);
echo "<h3>Server Status</h3>\r\n";
if ($api -> Result == "Error") die("Error: " . $api -> Error);
echo "Logins: " . $api -> Logins . "<br/>\r\n";
}
}
So basically i called loginNumber(), then it shows this error:*
Call to undefined function UserFrosting\testFunction()*
I had same problem with SoupClient but i shows this error:*
Class 'UserFrosting\SoapClient' not found*
here is my soapClient code in same namesapce:
public function templatePost(){
$client = SoapClient('https://www.test.com/pg/services/WebGate/wsdl', ['encoding' => 'UTF-8']);
$result = $client->PaymentRequest([
'MerchantID' => $MerchantID,
'Amount' => $Amount,
'Description' => $Description,
'Email' => $Email,
'Mobile' => $Mobile,
'CallbackURL' => $CallbackURL,
]);
if ($result->Status == 100) {
header('Location: https://www.test.com/pg/StartPay/'.$result->Authority);
} else {
echo'ERR: '.$result->Status;
}
}
I had the same error, what is my problem? how can i call these functions?
Explanation: You do not have a function testFunction, but the object GroupController has a method testFuntion. So you need to use $this->.. since you are already inside that class. Your loginNumber should read:
public function loginNumber(){
$params = array("Command" => "SystemStats");
$api = $this->testFunction($params);
echo "<h3>Server Status</h3>\r\n";
if ($api -> Result == "Error") die("Error: " . $api -> Error);
echo "Logins: " . $api -> Logins . "<br/>\r\n";
}
In your second question you are not importing the class SoapClient correctly. Please try:
$client = \SoapClient(...);
This uses SoapClient from root namespace.
I have this script to check the song title and streamname (DJ) listeners but it doesn't always work like it should
it should be if status 1 show what the stats grab else show offline. but it doesn't want to work, I got this code off a friend he doesn't want to recode it but I have no idea how to make it work with shoutcast 2.0
heres the code
<?php
class radioStuff {
/**
Shoutcast specific class to grab server stats
*/
private $url = "http://sc.*REMOVED*.co.uk";
private $port = 80;
private $json_object;
public function __construct() {
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$this->url . ':' . $this->port . '/stats?json=1');
// Execute
$result=curl_exec($ch);
// Closing
curl_close($ch);
$this->json_object = json_decode($result);
}
public function getHabboUrl() {
$imageString = 'http://www.habbo.com/habbo-imaging/avatarimage?user=' . $this->json_object->servergenre . '&direction=4&head_direction=3&action=wlk&gesture=sml';
return $imageString;
}
public function getCurrentListeners() {
return $this->json_object->currentlisteners;
}
public function getSTATUS() {
return $this->json_object->streamstatus;
}
public function getCurrentDJ() {
return $this->json_object->servertitle;
}
public function getCurrentSong() {
return $this->json_object->songtitle;
}
}
$radio = new radioStuff();
if($radio->getSTATUS == 1) {
$response = array(
'dj' => 'Radio statistics are offline!',
'song' => 'We are offline!', 'listeners' => ''
);
header('Content-Type: application/json');
echo json_encode($response);
} else {
$response = array(
'dj' => $radio->getCurrentDJ(),
'song' => $radio->getCurrentSong(),
'listeners' => $radio->getCurrentListeners()
);
header('Content-Type: application/json');
echo json_encode($response);
}
You have an error in you code:
if($radio->getSTATUS == 1) {
should be
if($radio->getSTATUS() == 1) {
getSTATUS is a function, so you should call it with ()
Also, if stream status is 1 - the stream is alive and if stream status is 0 - then your station is offline, so replace 1 with 0 in your comparison.
I am a beginner in PHP OOP.
I was wondering what is the best practice in PHP OOP and classes. Keep values in a Variables ($var) or keep them in the object ($this->var).
As you can see in below code I set the variables ($this->var) in methods and ,therefore, do not need to return anything from that method.
Is this a correct way of doing it or do I need to return somthing from method? and pass that value to the next method?
Below is a simple curl class for API that extracts a clients email address by using a code.
Pay specific attention to extract_ib_email() Method, no variable is passed to functions (Methods). Is this correct and is there a better way of doing it please?
//Parent Class
class CurlRequest
{
/* get the data from a URL */
protected function curl_get_data() {
$ch = curl_init();
//$timeout = 5;
curl_setopt($ch, CURLOPT_VERBOSE, $this->curloptVERBOSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->curloptSSLVERIFYPEER);
curl_setopt($ch, CURLOPT_URL, $this->curlURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, $this->curloptRETURNTRANSFER);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);
$data = curl_exec($ch);
if ($data === FALSE) {
printf("cUrl error (#%d): %s<br>\n", curl_errno($ch),
htmlspecialchars(curl_error($ch)));
}
//echo "<pre>"; print_r($data); echo "</pre>";
//var_dump($data);
curl_close($ch);
$this->data = $data;
return $data;
}
}
class GetIBEmail extends CurlRequest
{
private $ibRef;
function __construct($ibRef)
{
// Set Variables
$this->baseURL = 'https://www.example.com/api/iel/';
$this->ibRef = $ibRef;
//$this->ibCode = $ibCode;
//set curl options for this request specifically
$this->timeout = $timeout = 5;
$this->curloptVERBOSE = $curlopt_VERBOSE = true;
$this->curloptSSLVERIFYPEER = $curlopt_SSL_VERIFYPEER = false;
$this->curloptRETURNTRANSFER = $curlopt_RETURNTRANSFER = 1;
}
// IB Code form is like ib_xxx need to get the last 3 letters
private function getIBCode(){
$ibRefBits = explode('_', $this->ibRef);
$this->ibCode = $ibRefBits[1];
//return $this->ibCode;
}
//construct the curl url using the IB code
private function construct_ib_curl_url(){
//$url = 'https://www.example.com/api/iel/xxx';
//$url = $this->baseURL . $this->ibCode;
$this->curlURL = $this->baseURL . $this->ibCode;
//return $url;
}
// extract email from returned curl response
public function extract_ib_email() {
$this->getIBCode();
$this->construct_ib_curl_url();
$this->curl_get_data();
$resArr = array();
$resArr = json_decode($this->data);
echo "<pre>"; print_r($resArr); echo "</pre>";
$ib_email = $resArr[0]->email;
$this->ib_email = $ib_email;
return $ib_email;
}
}
//Set ibCode
$ibCode = 'ib_xxx'; //$_SESSION['ib_code'];
$ibEmail = new GetIBEmail($ibCode); //pass value to the construct function
echo '<br>' . $ibEmail->extract_ib_email() . '<br>';
I've been looking around hoping I could find the issue I'm stumbling upon... However I couldn't find it. I've made a class in PHP, within that class there is a function that connects to an API retrieving JSON data (this function has been tested and works like a charm). However now I'm trying to seperate the objects of the JSON data I receive into different functions.
I've only managed to parse the data now through a foreach and echo, but it'd be a hassle to do it like that constantly.
This is what it currently looks like so you get an idea.
EDIT
Issue has been resolved, the public function foo(); Had and $info variable which had a json_decode(); which interupted the next function to split the data.
class parseData{
var $name;
var $domain;
public function foo($name, $domain)
{
$this->name = $name;
$this->domain = $domain;
$ch = curl_init();
$user_agent = 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31';
$request_headers = array();
$request_headers[] = 'User-Agent: ' . $user_agent;
$request_headers[] = 'Accept: text/html,application/xhtml+xml,application/xml,application/json;q=0.9,*/*;q=0.8';
curl_setopt($ch, CURLOPT_URL, "https://www.xxx." . $domain . "/api/public/users?name=" . $name . "");
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, "https://www.xxx." . $domain . "/api/public/users?name=" . $name);
$id = json_decode(curl_exec($ch));
if (isset($id) && $id->profileVisible == 1) {
curl_setopt($ch, CURLOPT_URL, "https://www.xxx." . $domain . "/api/public/users/" . $id->uniqueId . "/profile");
$info = curl_exec($ch);
} else
$info = false;
curl_close($ch);
return $info;
}
public $response = array(), $user = array(), $friends = array(), $groups = array(), $rooms = array(), $badges = array();
public function __construct(){
$this->response = $this->foo("user", "nl");
$this->init();
}
// this function will split data into sub variables
private function init(){
$this->response =json_decode(file_get_contents($this->response), TRUE);
$this->user = $this->response['user'];
$this->friends = $this->response['friends'];
$this->groups = $this->response['groups'];
$this->rooms = $this->response['rooms'];
$this->badges = $this->response['badges'];
// free main response object
unset($this->response);
}
public function uid(){
echo $this->user['uniqueId'];
}
public function name(){
echo $this->user['name'];
}
public function membersince(){
echo $this->user['memberSince'];
}
public function motto(){
echo $this->user['motto'];
}
public function figure(){
echo $this->user['figureString'];
}
//this function will manipulate USER data.
public function user(){
echo "Naam: ".$this->user['name'].'<br/>';
echo "Motto: ".$this->user['motto'].'<br/>';
echo "Lid sinds: ".$this->user['memberSince'].'<br/>';
echo "Unique ID: ".$this->user['uniqueId'].'<br/>';
echo "figureString: ".$this->user['figureString'].'<br/>';
foreach($this->user['selectedBadges'] as $selectedBadge){
echo 'Badge index: '. $selectedBadge['badgeIndex'];
echo 'Badge code: '. $selectedBadge['code'];
echo 'Badge naam: '. $selectedBadge['name'];
echo 'Badge beschrijving: '. $selectedBadge['description'];
}
}
public function friends(){
//do stuff with $this->friends.
}
public function groups(){
//do stuff with $this->groups
}
//and other functions like badges and rooms etc.
}
$parser = new parseData();
$parser->user();
The API sends different objects back and I'd like to seperate them into different functions as "user", "friends", "groups" etc. in order to retrieve all the strings out of those objects. So my question is, is it possible to parse API data through different functions within the same class? If so, how do I do this? And will calling the function be an easier task to do as well or will it just be a hassle like doing the foreach method?
So, I've looked into your json and you can like this
class parseData{
public $response = array(), $user = array(), $friends = array(), $groups = array(), $rooms = array(), $badges = array();
public function __construct(){
$this->response = call_your_function_get_api_response();
$this->init();
}
// this function will split data into sub variables
private function init(){
$this->response = json_decode(file_get_contents('json.json'), TRUE);
//I'm using file get contents here, as I've stored your json into file.
// but you'll have to do like this
//$this->response = json_decode($this->response, TRUE);
$this->user = $this->response['user'];
$this->friends = $this->response['friends'];
$this->groups = $this->response['groups'];
$this->rooms = $this->response['rooms'];
$this->badges = $this->response['badges'];
// free main response object
unset($this->response);
}
/*
* I'm updating here with new function name(), so to print name only do this.
*/
public function name(){
echo "Name: ".$this->user['name'].'<br/>'; //This will print name only.
}
//this function will manipulate USER data.
public function user(){
echo "User's Unique ID: ".$this->user['uniqueId'].'<br/>';
echo "Name: ".$this->user['name'].'<br/>';
echo "figureString: ".$this->user['figureString'].'<br/>';
foreach($this->user['selectedBadges'] as $selectedBadge){
echo 'Badge index: '. $selectedBadge['badgeIndex'];
echo 'Badge code: '. $selectedBadge['code'];
echo 'Badge name: '. $selectedBadge['name'];
echo 'Badge description: '. $selectedBadge['description'];
}
}
public function friends(){
//do stuff with $this->friends.
}
public function groups(){
//do stuff with $this->groups
}
//and other functions like badges and rooms etc.
}
$parser = new parseData();
$parser->user();
/*
* and you can call function like this
* $parser->friends(); will process only friends data from json response
* $parser->groups(); will process only groups data from json response.
* ... rest of functions ...
*/
I've tested this with one iteration of stuff using users() function.
here is output
Edit
I've updated class with a new method name() so now to print only name,
$parser->name();
Another Edit
as per your comment
I'm putting __construct() code here again.
public function __construct(){
$get = new foo();
$this->response = $get->bar("person", "nl");
$this->init();
}
and rest of the things are same.
$parser = new parseData();
$parser->user();
$parser->name(); //will display name only.
putting all together
you need to update two functions
public function __construct(){
$this->response = json_decode($this->foo("user", "nl"), TRUE);
$this->init();
}
and in init() comment out the first line as it's not needed any more.
Hope this will help you.
I am new in studing php static function I want to build a function, curl some contents from some url, and then process php regex to get what I need. Here is my code, but the curl part runs twice. How to modify it so that short the run durante?
$url = 'www.php.net/archive/2012.php';
if (!$url){
exit;
}
echo TestClass::getTitle1($url);
echo '<hr />';
echo TestClass::getTitle2($url);
class TestClass
{
static function getTitle1($url)
{
$data = self::getHtml($url);// run in first time
preg_match("/(<h1.*>)(.*)(<\/h1>)/",$data,$h1tags);
$h1 = $h1tags[0];
if (!$h1) return false;
return $h1;
}
static function getTitle2($url)
{
$data = self::getHtml($url);// run in second time
preg_match("/(<h2.*>)(.*)(<\/h2>)/",$data,$h2tags);
$h2 = $h2tags[0];
if (!$h2) return false;
return $h2;
}
static function getHtml($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$htmls = curl_exec($ch);
curl_close($ch);
if (!$htmls) return false;
return $htmls;
}
}
Like commented pass h1/h2 as a parameter to your function and rewrite your replace function. Or run curl outside and pass the result to your replace function.
Like the others told you, do not repeat yourself and use parameters.
But incase you need the method for another class you may use in the future (use one-time called data in more than one different function) i have edited it for you
<?php
class TestClass{
protected static $data;
static function getTitle1($url){
//check if $data is set or not
$data = self::$data ? self::$data : self::getHtml($url);
//do your code here
preg_match("/(<h1.*>)(.*)(<\/h1>)/",$data,$h1tags);
$h1 = $h1tags[0];
if (!$h1) return false;
return $h1;
}
static function getTitle2($url){
//check if $data is set or not
$data = self::$data ? self::$data : self::getHtml($url);
//do your code here
preg_match("/(<h1.*>)(.*)(<\/h1>)/",$data,$h1tags);
$h1 = $h1tags[0];
if (!$h1) return false;
return $h1;
}
static function getHtml($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$htmls = curl_exec($ch);
curl_close($ch);
if (!$htmls) return false;
//ADD THIS LINE TO YOUR CODE AS WELL
self::$data = $htmls;
return $htmls;
}
}
$url = 'www.php.net/archive/2012.php';
$class = new TestClass();
echo $class->getTitle1($url);
echo '<hr />';
echo $class->getTitle2($url);
?>