I started using OOP in PHP for first time, and I dont know how to achieve the following structure for my variables:
$this->myData->generalData->title;
$this->myData->generalData->description;
$this->myData->amount;
$this->myData->addNewData();
Up till now, what I am achieving is a normal variable inside a class:
$this->variablename
I tried doing this code, but it's not working at all:
$this->CDNE = "CDNE";
$this->CDNE->FOLDER = "hello man";
Can you explain me, how all this works?
Just to ilustrate my comment. Doing it with sub-objects could be something like this (a very basic example without attributes initialization):
class GeneralData{
public $title;
public $description;
}
class MyData{
public $generalData;
public $amount;
function __construct(){
$this->generalData = new GeneralData();
}
function addNewData(){
}
}
class MainClass{
public $myData;
function __construct(){
$this->myData = new MyData();
}
}
Related
I am struggling with some PHP code here. Like the title says, I am trying to pass an instance of a Class as a parameter to a function (Note, this file is in another file and has a different scope, and thus I need to pass it as a parameter).
This is the code I have currently set up:
// requires built this page, the classes and the functions are in seperate files.
// That's why I need to pass it in as a parameter.
class ClassName {
private $name;
private $age;
public function getAge(){
return $this->age;
}
} $className = new ClassName();
// seperate file
var_dump($className); // works, but has no methods.
function randomFunc($className){
echo $className->getAge(); // call to undefined method className::getAge()
} randomFunc($className);
EDIT 2:
I have uploaded my code here:
http://sandbox.onlinephpfunctions.com/code/99954d61ca4d3f53ce549dab9f8333630633d89c
I hope you people can help me, any help would be much appreciated.
This works fine:
<?php
class ClassName {
private $name;
private $age = 19;
public function getAge(){
return $this->age;
}
}
function randomFunc($className){
echo $className->getAge(); // call to undefined method className::getAge()
}
$className = new ClassName();
randomFunc($className);
Outputs: 19
Your code also runs fine for me, it just outputs nothing since $age is empty.
What version of PHP are you running?
I think I have more or less managed to get a grasp on OOP/Inheritance, and the basics of method chaining I think I understood as well. However I am still confused about how to actually use some of it.
I wanted to do something that I've seen when working with Magento before:
In Magento, I've seen some sort of "selector-function" used in method chaining. It's a little hard to put into words, but it was something along the lines of:
$categoryName = Mage::getModel('catalog/category')->load($categoryId)->getName();
It's the load($categoryId) part that interests me, as in, a function that selects some instance of something and allows me to run a function on that specific instance.
Now, I am writing a module that allows me to configure certain promotions on our website. Seeing as we'll have many different promotions and I want them to be easily configurable and modifiable, I wanted to do something similar.
So, if I wanted to be able to do something like this:
$prm = new Promotion();
$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');
$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
$prm->getPromo('nyPromo')->setName('Promotion for New Years!');
echo $prm->getPromo('xmasPromo')->getName(); // returns: Promotion for Xmas!
echo $prm->getPromo('nyPromo')->getName(); // returns: Promotion for New Years!
How would the class definition for that have to look like?
This may be much more simple or much more complicated than I anticipate. In either case, thanks a lot!
Edit:
So I did some testing around with the info deceze gave me, but I'm still confused.
Bad naming and putting 2 classes in 1 file aside, here's what I did:
class file:
class Promotion {
private $__arr = array();
public function addPromo($name) {
$this->__arr[$name] = new Promo();
}
public function getPromo($name) {
$this->__arr[$name];
}
}
class Promo {
private $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $name;
}
}
and the run file:
require_once 'class.php';
error_reporting(E_ALL);
$prm = new Promotion();
$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');
$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
$prm->getPromo('nyPromo')->setName('Promotion for New Years!');
echo 'X: '.$prm->getPromo('xmasPromo')->getName(); // returns: Promotion for Xmas!
echo "\n";
echo 'N: '.$prm->getPromo('nyPromo')->getName(); // returns: Promotion for New Years!
This gives me Fatal error: Call to a member function setName() on a non-object in /var/www/test/index.php on line 11.
But why? Shouldn't getPromo() give me back the object?
Thanks again..
Thanks to the great guys here, it works now. In case anyone were to pass by here with the same or a similar question, here's the final, working code:
Classes:
class Promotion {
private $__arr = array();
public function addPromo($name) {
$this->__arr[$name] = new Promo();
}
public function getPromo($name) {
return $this->__arr[$name];
}
}
class Promo {
private $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
Test file:
require_once 'class.php';
error_reporting(E_ALL);
$prm = new Promotion();
$prm->addPromo('xmasPromo');
$prm->addPromo('nyPromo');
$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
$prm->getPromo('nyPromo')->setName('Promotion for New Years!');
echo 'X: '.$prm->getPromo('xmasPromo')->getName(); // returns: Promotion for Xmas!
echo "\n";
echo 'N: '.$prm->getPromo('nyPromo')->getName(); // returns: Promotion for New Years!
Method chaining is really simple, all it does is use one particular element of PHP's syntax:
When a function returns an object, you can directly continue with -> after that function.
The longhand version can be:
$bar = $foo->bar();
$baz = $bar->baz();
echo $baz;
$foo->bar() returns an object ($bar) which has a method baz(), and that method returns some value ($baz). This can be written in shorthand like so:
echo $foo->bar()->baz();
$foo->bar() still returns an object which has a method baz(), so you can directly call it without assigning it to an intermediate variable. Maybe this makes it more obvious:
echo ( $foo->bar() )->baz();
You're calling the baz() method on whatever $foo->bar() returns.
$prm->getPromo('xmasPromo')->setName('Promotion for Xmas!');
As such, in your above case, all you need to do is to return an object which has the method setName from getPromo. I would assume getPromo is supposed to return some object of, say, the Promo class. If the Promo class has a method setName, you're all set.
If you want to chain methods you just need to always return the object like this
class Chain {
public function firstChain() {
//do something
return $this;
}
public function secondChain() {
//do some stuff
return $this;
}
}
Than when you have an instance of the class you do like this:
$obj = new Chain();
$obj->fistChain()->secondChain();
this is a super basic question but my classes are not working the way I expect them to. I am a CS student in my second year so go easy on me! The only other language I know is Java. Here is my class, called class.Team.php (represents a team).
<?php
class Team
{
private $teamId='';
private $teamName='Tyler';
private $teamCity='';
private $homeField='';
private $headCoach='';
private $mascot='';
private $wins=0;
private $losses=0;
private $roster;
function display(){
return $teamName;
}
}
?>
So when I call the display() method it should return a string (hardcoded as "tyler). Here is my test script. It is simply displaying nothing. A blank white page. Am I missing something??
<?php
include ('class.Team.php');
$um = new Team;
$string = $um->display();
print ($string);
?>
THANKS!
You need to use the $this keyword.
function display(){
return $this->teamName;
}
It's not Java. You have to use $this to reference own instance.
return $this->teamName;
I am looking to incorporate a testing framework into a project I am building and came across Enhance PHP which I like but I am having some difficulty finding relevant information on-line since "enhance php" is such a commonly used phrase.
Has anyone worked with this framework that might be able to point me toward some helpful guide? Have you worked with a unit test framework that you think is amazingly better?
Thanks in advance.
In response to Gotzofter, this is the class to be tested:
<?php
include_once('EnhanceTestFramework.php');
class ExampleClass
{
private $OtherClass;
function __construct($mock = null)
{
if ($mock == null)
$this->OtherClass = new OtherExampleClass();
else
$this->OtherClass = $mock;
}
public function doSomething()
{
return $this->OtherClass->getSomething(1, 'Arg2');
}
}
class OtherExampleClass
{
public function getSomething()
{
return "Something";
}
}
class ExampleClassTests extends \Enhance\TestFixture
{
public function setUp()
{
}
public function tearDown()
{
}
public function verifyWithAMock()
{
$mock = \Enhance\MockFactory::createMock('OtherExampleClass');
$mock->addExpectation(
\Enhance\Expect::method('getSomething')
->with(1, 'Arg2')
->returns('Something')
->times(1)
);
$target = new ExampleClass($mock);
$result = $target->doSomething();
\Enhance\Assert::areIdentical("Something", $result);
$mock->verifyExpectations();
}
}
\Enhance\Core::runTests();
look at my constructor for ExampleClass.
Because enhance-php's site example injects the $mock object by calling new ExampleClass($mock), I am forced to change my ExampleClass constructor to handle a $mock as an input parameter.
Do I have to handle this for all classes that I want to subject to unit testing with the framework?
Thanks.
This:
function __construct()
{
$this->OtherClass = new OtherExampleClass;
}
Should be:
function __construct($otherClass)
{
$this->OtherClass = $otherClass;
}
Your mock is never injected at this point in your test:
$target = new ExampleClass($mock);
One thing I would recommend no matter what testing framework you are using is type-hinting against the expected class, or interface.
<?php
class ExampleClass
{
private $OtherClass; // OtherClass instance
public function __construct(OtherClass $OtherClass=null)
{
// ...
}
}
I'm no di expert, but I don't see the problem in letting each class call new if an instance isn't provided for a particular dependency. You could also of course take the approach where you use setter methods to configure dependencies.
<?php
class class ExampleClass
{
private $OtherClass; // OtherClass instance
public function setOtherClass(OtherClass $OtherClass)
{
$this->OtherClass = $OtherClass;
}
}
It is lame that the ExampleClass in the sample code doesn't even define the doSomething method from the ExampleDependencyClassTests, but if I understand correctly it looks like Enhance PHP is not forcing you to take a particular style of dependency injection. You can write the test class however you want, so for example if you took the setter method approach I mentioned above, you could change the example mock code to
<?php
class ExampleDependencyClassTests extends \Enhance\TestFixture
{
public function verifyWithAMock()
{
$mock = \Enhance\MockFactory::createMock('ExampleDependencyClass');
$mock->addExpectation(
\Enhance\Expect::method('getSomething')
->with(1, 'Arg2')
->returns('Something')
->times(1)
);
$target = new ExampleClass();
$target->setExampleDependencyClass($mock);
$result = $target->doSomething();
$mock->verifyExpectations();
}
}
Of course it would probly make sense to make the appropriate revisions to the ExampleClass!
<?php
class ExampleClass
{
private $ExampleDependencyClass;
public function addTwoNumbers($a, $b)
{
return $a + $b;
}
public function setExampleDependencyClass(
ExampleDependencyClass $ExampleDependecyClass
) {
$this->ExampleDependecyClass = $ExampleDependecyClass;
}
public function doSomething($someArg)
{
return 'Something';
}
}
I've worked with PHPUnit quite a bit, and honestly you'll have to face the same challenges with Mocks there. My 2 cents, try to model your tests without Mocks if possible ;)
There is a tutorial on NetTuts titled Testing Your PHP Codebase With Enhance PHP, which will definitely help you to get started.
And there is a Quick Start Guide on Enhance PHP.
I have a simple question regarding PHP Classes.
Multiple times I have seen other class-frameworks etc use method calls like.
$post->data->text();
I like this functionality, rather than just doing something like this.
$post->dataReturnAsText();
But i'm not quite sure how they created this functionality to have perhaps a 'sub-method'? Hope someone can point me in the right direction....
The example you provide has nothing special:
<?php
class Post{
public $data;
}
class Data{
public function text(){
}
}
$post = new Post;
$post->data = new Data;
$post->data->text();
However, you've probably found it in the context of method chaining (very popular in JavaScript libraries):
<?php
class Foo{
public function doThis(){
return $this;
}
public function doThat(){
return $this;
}
}
$foo = new Foo;
$foo->doThis()->doThat()->doThis();
In this case, data is simply a attribute of the class, and it contains another object:
class data
{
public function text()
{
}
}
class thing
{
public $data;
}
$thing = new thing();
$thing->data = new data();
$thing->data->text();
its probably a just that the "data" is a a public property of $post containing an object wth a text property for example :
class Textable {
public $text;
function __construct($intext) {
$this->text = $intext;
}
}
class Post {
public $data;
function __construct() {
$data = new Textable("jabberwocky");
}
}
this will allow you to do :
$post = new Post();
echo( $post->data->text ); // print out "jabberwocky"
of course the right OOP way is to make the property private and allow access useing a getter function but that besides the point...