Send back to Ajax with OOP - php

New to OOP, figured I'd practice a bit by sending back data from PHP via ajax. What am I doing wrong here? It works if I change the code to procedural. Here's the OOP:
if (isset($_POST['fruity'])) {
$start_fruity = new Fruity_draft();
$start_fruity->send_json();
}
class Fruity_draft {
public $banned = $_POST['banned'];
public $players = $_POST['players'];
public $random_civs = $_POST['random_civs'];
public $array_list = [];
public $send_json['banned'] = $banned;
function __construct($send_json) {
$this->send_json = $send_json;
}
function send_json() {
echo json_encode($this->send_json);
}
}

First of all, you forgot about passing a parameter to the constructor, it expects an array.
function __construct($send_json) {
In your call, you don't send anything
$start_fruity = new Fruity_draft();
This throws a warning, Warning: Missing Argument 1
and a notice, Notice: Undefined variable: send_json
Second, you should move the initialization of the class variables in the constructor.
class Fruity_draft {
public $banned;
public $players;
public $random_civs;
public $array_list;
public $send_json;
function __construct($send_json) {
$this->banned = 'banned';
$this->players = 'players';
$this->random_civs = 'random_civs';
$this->send_json = $send_json;
$this->send_json['banned'] = $this->banned;
}
...
}

That's not really OOP :). You should return something from the class, not echo.
Also, you should send data from other function to the class.. in the constructor or with a method set_post_data() or something...
Simple:
if (isset($_POST['fruity'])) {
$start_fruity = new Fruity_draft($_POST);
echo $start_fruity->get_json_response();
}
class Fruity_draft {
private $postData;
function __construct($postData) {
$this->postData = $postData;
}
function get_json_response() {
return json_encode($this->postData['banned']);
}
}

Related

how create static class with function after function call same as eloquent or may jquery

I don't know what is this call system.
For example:
$a = SameClass::fnc1()->fnc2('input')->fnc2();
and we can see this method in jQuery:
$("#selector").parent().css('left',5).fadeOut(1500);
I don't have any idea to write this codes structure in PHP.
You just need to return object from a function
For example
class First
{
public function funcFirst()
{
$obj = new Second;
return $obj;
}
}
class Second
{
public function funcSecond($message)
{
return $message;
}
}
$first = new First;
$message = "Hello";
$result = $first->funcFirst()->funcSecond($message); // 'Hello'

How To Get Variable From Constructor So It Can Be Used In Other Functions?

I have this code :
<?php
class Email{
public $mandrill_host;
public function __construct() {
$this->config_ini = parse_ini_file($_SERVER['DOCUMENT_ROOT'] . '/config.ini', true);
$this->mandrill_host = $config_ini['mandrill']['host'];
}
public function sendEmail () {
$res = $this->mandrill_host;
return $res;
}
}
$test = new Email;
echo $test->sendEmail ();
?>
and it gives me an empty result. it seems that the constructor method doesn't give the variable needed in sendEmail function. even though I already declared as public variable in class level.
how to get $this->mandrill_host from constructor so I can use it in any other method? what did I miss here?
Try
class Email{
public $mandrill_host;
public $config_ini; //you are missing this
public function __construct() {
$this->config_ini = parse_ini_file($_SERVER['DOCUMENT_ROOT'] . '/config.ini', true);
$this->mandrill_host = $this->config_ini['mandrill']['host'];
}
public function sendEmail () {
$res = $this->mandrill_host;
return $res;
}
}
$test = new Email;
echo $test->sendEmail ();
?>

Using global variable in my class causing unexpected syntax

I have a class that requires a variable that is defined out of the scope of it. So i tried using global but, this causes this error:
syntax error, unexpected 'global' (T_GLOBAL), expecting function (T_FUNCTION)
I am unsure if I have put it in the wrong place or using the global keyword incorrectly.
My code looks like this:
$data = new testClass();
class System
{
private $values;
global $data;
public function __construct()
{
}
public function test()
{
return $data->get();
}
}
$system = new System();
echo $system->test();
So i was wondering how do I get the $data variable to be defined in my class? My use of global seems to be incorrect, I also put the global declaration in the __contrust() function but that didn't work either.
Define the global variable within the function instead of the class:
public function test()
{
global $data;
return $data->get();
}
EDIT: Alternate idea:
class System
{
private $values;
private $thedata;
public function __construct($data)
{
$this->thedata = $data;
}
public function test()
{
return $this->thedata->get();
}
}
$data = new testClass();
$system = new System($data);
echo $system->test();
So i was wondering how do I get the $data variable to be defined in my class? My use of global seems to be incorrect, I also put the global declaration in the __contrust() function but that didn't work either.
If you really want to use bad global construction, you should do like this:
class System
{
private $values;
// removed global from here
public function __construct()
{
}
public function test()
{
// added global here
global $data;
return $data->get();
}
}
But OOP principles recommend us to use composition, not global variables. So you can pass the $data into your another class via constructor or via setter. Here's some code implementing both approaches:
class testClass {
public function get()
{
echo __CLASS__.'::'.__FUNCTION__;
}
}
class System
{
private $values;
private $data;
public function __construct(testClass $data = null)
{
if ($data) {
$this->data = $data;
}
}
public function setData(testClass $data)
{
$this->data = $data;
}
public function test()
{
return $this->data->get();
}
}
$data = new testClass();
// via constructor
$system = new System($data);
// or via setter
$system = new System;
$system->setData($data);
echo $system->test();
You could pass $data when you instantiate the class and then assign it in the constructor, which will make it available to all the methods of the class.
class System {
public $data;
public function __construct($data) {
$this->data = $data;
}
public function index() {
echo $this->data;
}
}
$data = 'foo';
$system = new System($data);
echo $system->index();
outputs 'foo';
First things first... This could just be a simple "bad PHP syntax" issue. Look for forgotten ; or in my case... Forgetting that functions actually need the word function : )

How to test specific methods with PHPUnit

I need help with PHPUnit and some methods. How should you guys write tests in PHPUnit to reach a high code coverage for the following properties and methods?
I'm pretty new to PHPUnit and could need some help. I've just write some test cases for more basic code. This class generates flash messages for the end user, and store it in a session.
Extremely grateful for some help. Any ideas?
private $sessionKey = 'statusMessage';
private $messageTypes = ['info', 'error', 'success', 'warning']; // Message types.
private $session = null;
private $all = null;
public function __construct() {
if(isset($_SESSION[$this->sessionKey])) {
$this->fetch();
}
}
public function fetch() {
$this->all = $_SESSION[$this->sessionKey];
}
public function add($type = 'debug', $message) {
$statusMessage = ['type' => $type, 'message' => $message];
if (is_null($this->all)) {
$this->all = array();
}
array_push($this->all, $statusMessage);
$_SESSION[$this->sessionKey] = $this->all;
}
public function clear() {
$_SESSION[$this->sessionKey] = null;
$this->all = null;
}
public function html() {
$html = null;
if(is_null($this->all))
return $html;
foreach ($this->all as $message) {
$type = $message['type'];
$message = $message['message'];
$html .= "<div class='message-" . $type . "'>" . $message . "</div>";
}
$this->clear();
return $html;
}
I have setup an setup-case, like this:
protected function setUp() {
$this->flash = new ClassName();
}
Also tried one test case:
public function testFetch() {
$this->assertEquals($this->flash->fetch(), "statusMessage", "Wrong session key.");
}
But gets an error message telling me: "Undefined variable: _SESSION"
If I then try:
public function testFetch() {
$_SESSION = array();
$this->assertEquals($this->flash->fetch(), "statusMessage", "Wrong session key.");
}
I get another error message telling: "Undefined index: statusMessage"
Try something like this:
function testWithoutSessionKey() {
$_SESSION = array();
$yourClass = new YourclassName();
$this->assertNull($yourClass->html()); }
function testWithSomeSessionKey() {
$_SESSION = array( 'statusMessage' => array(...));
$yourClass = new YourclassName();
$this->assertSame($expect, $yourClass->html());
}
You can't instantiate your class in the setup because your constructor need that the SESSION variable may exist(so you can test that can have some value inside).
You can evalutate (assert) only the ouptput of a method, so you can't assert that the message of the return of the method fetch.
In your method testFecth you have found a bug! Thanks to the test for this. Try fixing it with checking as you do in the construct :
public function fetch() {
if (isset($_SESSION[$this->sessionKey]))
$this->all = $_SESSION[$this->sessionKey];
}
Hope this help

The correct way of doing delegates or callbacks in PHP

I need to implement the following pattern in php:
class EventSubscriber
{
private $userCode;
public function __construct(&$userCode) { $this->userCode = &$userCode; }
public function Subscribe($eventHandler) { $userCode[] = $eventHandler; }
}
class Event
{
private $subscriber;
private $userCode = array();
public function __construct()
{
$this->subscriber = new Subscriber($this->userCode)
}
public function Subscriber() { return $this->subscriber; }
public function Fire()
{
foreach ($this->userCode as $eventHandler)
{
/* Here i need to execute $eventHandler */
}
}
}
class Button
{
private $eventClick;
public function __construct() { $this->eventClick = new Event(); }
public function EventClick() { return $this->eventClick->Subscriber(); }
public function Render()
{
if (/* Button was clicked */) $this->eventClick->Fire();
return '<input type="button" />';
}
}
class Page
{
private $button;
// THIS IS PRIVATE CLASS MEMBER !!!
private function ButtonClickedHandler($sender, $eventArgs)
{
echo "button was clicked";
}
public function __construct()
{
$this->button = new Button();
$this->button->EventClick()->Subscribe(array($this, 'ButtonClickedHandler'));
}
...
}
what is the correct way to do so.
P.S.
I was using call_user_func for that purpose and believe it or not it was able to call private class members, but after few weeks of development i've found that it stopped working. Was it a bug in my code or was it some something else that made me think that 'call_user_func' is able call private class functions, I don't know, but now I'm looking for a simple, fast and elegant method of safely calling one's private class member from other class. I'm looking to closures right now, but have problems with '$this' inside closure...
Callbacks in PHP aren't like callbacks in most other languages. Typical languages represent callbacks as pointers, whereas PHP represents them as strings. There's no "magic" between the string or array() syntax and the call. call_user_func(array($obj, 'str')) is syntactically the same as $obj->str(). If str is private, the call will fail.
You should simply make your event handler public. This has valid semantic meaning, i.e., "intended to be called from outside my class."
This implementation choice has other interesting side effects, for example:
class Food {
static function getCallback() {
return 'self::func';
}
static function func() {}
static function go() {
call_user_func(self::getCallback()); // Calls the intended function
}
}
class Barf {
static function go() {
call_user_func(Food::getCallback()); // 'self' is interpreted as 'Barf', so:
} // Error -- no function 'func' in 'Barf'
}
Anyway, if someone's interested, I've found the only possible solution via ReflectionMethod. Using this method with Php 5.3.2 gives performance penalty and is 2.3 times slower than calling class member directly, and only 1.3 times slower than call_user_func method. So in my case it is absolutely acceptable. Here's the code if someone interested:
class EventArgs {
}
class EventEraser {
private $eventIndex;
private $eventErased;
private $eventHandlers;
public function __construct($eventIndex, array &$eventHandlers) {
$this->eventIndex = $eventIndex;
$this->eventHandlers = &$eventHandlers;
}
public function RemoveEventHandler() {
if (!$this->eventErased) {
unset($this->eventHandlers[$this->eventIndex]);
$this->eventErased = true;
}
}
}
class EventSubscriber {
private $eventIndex;
private $eventHandlers;
public function __construct(array &$eventHandlers) {
$this->eventIndex = 0;
$this->eventHandlers = &$eventHandlers;
}
public function AddEventHandler(EventHandler $eventHandler) {
$this->eventHandlers[$this->eventIndex++] = $eventHandler;
}
public function AddRemovableEventHandler(EventHandler $eventHandler) {
$this->eventHandlers[$this->eventIndex] = $eventHandler;
$result = new EventEraser($this->eventIndex++, $this->eventHandlers);
return $result;
}
}
class EventHandler {
private $owner;
private $method;
public function __construct($owner, $methodName) {
$this->owner = $owner;
$this->method = new \ReflectionMethod($owner, $methodName);
$this->method->setAccessible(true);
}
public function Invoke($sender, $eventArgs) {
$this->method->invoke($this->owner, $sender, $eventArgs);
}
}
class Event {
private $unlocked = true;
private $eventReceiver;
private $eventHandlers;
private $recursionAllowed = true;
public function __construct() {
$this->eventHandlers = array();
}
public function GetUnlocked() {
return $this->unlocked;
}
public function SetUnlocked($value) {
$this->unlocked = $value;
}
public function FireEventHandlers($sender, $eventArgs) {
if ($this->unlocked) {
//защита от рекурсии
if ($this->recursionAllowed) {
$this->recursionAllowed = false;
foreach ($this->eventHandlers as $eventHandler) {
$eventHandler->Invoke($sender, $eventArgs);
}
$this->recursionAllowed = true;
}
}
}
public function Subscriber() {
if ($this->eventReceiver == null) {
$this->eventReceiver = new EventSubscriber($this->eventHandlers);
}
return $this->eventReceiver;
}
}
As time passes, there are new ways of achieving this.
Currently PSR-14 is drafted to handle this use case.
So you might find any of these interesting:
https://packagist.org/?query=psr-14

Categories