PHP including external files which use class fields from base file - php

Let's say I have a class...
class A {
private $action;
private $includes;
public function __construct($action, $file) {
//assign fields
}
public function includeFile()
include_once($this->file);
}
$a = new A('foo.process.php', 'somefile.php');
$a->includeFile();
As you can see, includeFile() calls the include from within the function, therefore once the external file is included, it should technically be inside of the function from my understanding.
After I've done that, let's look at the file included, which is somefile.php, which calls the field like so.
<form action=<?=$this->action;?> method="post" name="someForm">
<!--moar markup here-->
</form>
When I try to do this, I receive an error. Yet, in a CMS like Joomla I see this accomplished all the time. How is this possible?
Update
Here's the error I get.
Fatal error: Using $this when not in object context in /var/www/form/form.process.php on line 8
Update 2
Here's my code:
class EditForm implements ISave{
private $formName;
private $adData;
private $photoData;
private $urlData;
private $includes;
public function __construct(AdData $adData, PhotoData $photoData, UrlData $urlData, $includes) {
$this->formName = 'pageOne';
$this->adData = $adData;
$this->photoData = $photoData;
$this->urlData = $urlData;
$this->includes = $includes;
}
public function saveData() {
$this->adData->saveData();
$this->photoData->saveData();
}
public function includeFiles() {
if (is_array($this->includes)) {
foreach($this->includes as $file) {
include_once($file);
}
} else {
include_once($this->includes);
}
}
public function populateCategories($parent) {
$categories = $this->getCategories($parent);
$this->printCategories($categories);
}
public function populateCountries() {
$countries = $this->getCountries();
$this->printCountries($countries);
}
public function populateSubCategories() {
//TODO
}
private function getCategories($parent) {
$db = patentionConnect();
$query =
"SELECT * FROM `jos_adsmanager_categories`
WHERE `parent` = :parent";
$result = $db->fetchAll(
$query,
array(
new PQO(':parent', $parent)
)
);
return $result;
}
private function getCountries() {
$db = patentionConnect();
$query =
"SELECT `fieldtitle` FROM `jos_adsmanager_field_values`
WHERE fieldid = :id";
$result = $db->fetchAll(
$query,
array(
new PQO(':id', 29)
)
);
return $result;
}
private function printCountries(array $countries) {
foreach($countries as $row) {
?>
<option value=<?=$row['fieldtitle'];?> >
<?=$row['fieldtitle'];?>
</option>
<?php
}
}
private function printCategories(array $categories) {
foreach($categories as $key => $row){
?>
<option value=<?=$row['id'];?>>
<?=$row['name'];?>
</option>
<?php
}
}
}
And the include call (which exists in the same file):
$template = new EditForm(
new AdData(),
new PhotoData(),
new UrlData($Itemid),
array(
'form.php',
'form.process.php'
)
);
$template->includeFiles();
And the main file which is included...
if ($this->formName == "pageOne") {
$this->adData->addData('category', $_POST['category']);
$this->adData->addData('subcategory', $_POST['subcategory']);
} else if ($this->formName == "pageTwo") {
$this->adData->addData('ad_Website', $_POST['ad_Website']);
$this->adData->addData('ad_Patent', $_POST['ad_Patent']);
$this->adData->addData('ad_Address', $_POST['ad_Address']);
$this->adData->addData('email', $_POST['email']);
$this->adData->addData('hide_email', $_POST['hide_email']);
$this->adData->addData('ad_phone', $_POST['ad_phone']);
$this->adData->addData('ad_Protection', $_POST['ad_Protection']);
$this->adData->addData('ad_Number', $_POST['ad_Number']);
$this->adData->addData('ad_Country', $_POST['ad_Country']);
$this->adData->addData('ad_issuedate', $_POST['issuedate'] . '/' . $_POST['issuemonth'] . '/' . $_POST['issueyear']);
} else if ($this->formName == "pageThree") {
$this->adData->addData('name', $_POST['name']);
$this->adData->addData('ad_Background', $_POST['ad_Background']);
$this->adData->addData('ad_opeartion', $_POST['ad_operation']);
$this->adData->addData('ad_advlimit', $_POST['ad_advlimit']);
$this->adData->addData('ad_status', $_POST['ad_status']);
$this->adData->addData('ad_addinfo', $_POST['ad_addinfo']);
$this->adData->addData('ad_description', $_POST['ad_description']);
$this->adData->addData('tags', $_POST['tags']);
$this->adData->addData('videolink', $_POST['videolink']);
} else if ($this->formName == "pageFour") {
foreach($_POST['jos_photos'] as $photo) {
$this->photoData->addData(
array(
'title' => $photo['title'],
'url' => $photo['url'],
'ad_id' => $this->photoData->__get('ad_id'),
'userid' => $this->photoData->__get('userid')
)
);
}
}

Update
Strange: while the error itself hadn't been quite related to what the problem was, I found that it was simply an undefined field which I hadn't implemented.
Consider this thread solved. To those who replied, I certainly appreciate it regardless.

This should work. Are you sure you're doing the include from a non-static method that's part of the class (class A in your example)? Can you post the exact code you're using?
Edit: As general advice for problems like this, see if you can trim down the code so the problem is reproducible in a short, simple example that anyone could easily copy/paste to reproduce the exact error. The majority of the time, you'll figure out the answer yourself in the process of trying to simplify. And if you don't, it will make it much easier for others to help you debug.

Related

What i'm doing wrong here? [duplicate]

This question already has answers here:
Reference - What does this error mean in PHP?
(38 answers)
Closed 5 years ago.
So, i'm working on building my first MVC based application.
I followed this tutorial: requiremind.com/a-most-simple-php-mvc-beginners-tutorial/ and now i'm creating a forum based on the above tutorial.
This is in my index.php
if(isset($_GET['controller']) && !isset($_GET['action'])) {
$controller = $_GET['controller'];
$action = 'topic';
} else {
$controller = 'main';
$action = 'index';
}
The first condition is for displaying pages with topic and will work for url with ?controller=PHP or something like this and set the $action as 'topic'.
Now the request will be transferred to routes.php
function call($controller, $action) {
require_once('controllers/main_controller.php');
if($controller == 'main') {
require_once('models/main_model.php');
$controller = new MainController();
} else {
require_once('models/topic_model.php');
$controller = new MainController();
}
$controller->$action();
}
$db = Db::getInstance();
$query = $db->query('SELECT cat_name FROM category');
$categories = $query->fetchAll();
foreach($categories as $category_name) {
if($controller == $category_name && $action == 'topic') {
call($controller, $action);
}
}
if(($controller == 'main') && ($action == 'index')) {
call($controller, $action);
}
Now this will make a request with database and if the topic/category exists, it will call the function.
main_controller.php
class MainController {
public function index() {
$category = Main::home();
require_once('views/home.php');
}
public function topic() {
$topics = Topic::thread_topic($_GET['controller']);
require_once('views/topic.php');
}
}
After the main_controller.php, topic_model.php:
<?php
class Topic {
public $thread_topic;
public $thread_desc;
public $thread_created_at;
public $thread_created_by;
public $category_id;
public function __construct($thread_topic, $thread_desc, $thread_created_at, $thread_created_by, $category_id) {
$this->thread_topic = $thread_topic;
$this->thread_desc = $thread_desc;
$this->thread_created_at = $thread_created_at;
$this->thread_created_by = $thread_created_by;
$this->category_id = $category_id;
}
public function thread_topic($controller) {
$list = [];
$cat_id = Fnct::cat_name_to_id($controller);
$db = Db::getInstance();
$stmt = prepare('SELECT * FROM thread WHERE thread_created_by =:cat_id');
$stmt->execute(array(':cat_id' => $cat_id));
foreach($stmt->fetchAll() as $thread) {
$list[] = new Topic($thread['thread_topic'], $thread['thread_desc'], $thread['thread_created_at'], $thread['thread_created_by'], $thread['category_id']);
}
return $list[];
}
}
?>
And now the views/topic.php
<table border='1'>
<tr>
<th>Thread Topic</th>
<th>Thread Desc</th>
<th>Thread Started At</th>
</tr>
<tr>
<?php foreach($topics as $topic) { ?>
<td><?php echo $topic->thread_topic; ?></td>
<td><?php echo $topic->thread_desc; ?></td>
<td><?php echo $topic->thread_created_at; ?></td>
<?php } ?>
</tr>
</table>
The problem is this, it is displaying blank page. And giving no error.
And i'm still struggling to figure out what is wrong here. Please tell me what i did wrong here??
Edit: In routes.php moves $controller = new MainController() under if statement. But still same blank page is displaying.
Well, your error is in your routes.php as mentioned above. I'll try to explain it here in an answer and also directly fix the mistakes you did.
Okay, lets start. First of all, lets ignore the call() function first and only look at the other part:
Your Code:
$db = Db::getInstance();
$query = $db->query('SELECT cat_name FROM category');
$categories = $query->fetchAll();
foreach($categories as $category_name) {
if($controller == $category_name && $action == 'topic') {
call($controller, $action);
}
}
if(($controller == 'main') && ($action == 'index')) {
call($controller, $action);
}
You should know that fetchAll() will always return an arrqay, not a string, thats why you can't compare the result directly with a string. Change the code to:
$db = Db::getInstance();
$query = $db->query('SELECT cat_name FROM category');
$categories = $query->fetchAll();
foreach($categories as $category_name) {
if($controller == $category_name["cat_name"] && $action == 'topic') {
call($controller, $action);
}
}
if(($controller == 'main') && ($action == 'index')) {
call($controller, $action);
}
You see the $categoriy_name["cat_name"] - You have to give the key, since $category_name is an array, not a string. (May look at some tutorials for PHP and SQL, like how all the fetch method works and what their output is).
And then the second part, your call function
Your code:
function call($controller, $action) {
require_once('controllers/main_controller.php');
$controller = new MainController();
if($controller == 'main') {
require_once('models/main_model.php');
} else {
require_once('models/topic_model.php');
}
$controller->$action();
}
So, you pass $controller as an argument to that function. Thats correct. But then you assign $controller = new MainController(); so $controller is no longer the string you passed to the function, but now ins an object of the class MainController. So you loose your value on what you passed to the function. And then only 1 Line after you do:
if($controller == 'main') {
This will never be true. At this point $controller is an object of your mainController() and the argument will always evaluate to false, so you'll always load the topic_model.php Since your topic() function is inside the MainController() its okay, but its not what MVC is for. Thats just.. some random code there. Thats not MVC, nor good practice.
But well, I don't know what you want to do there with your main controller, I'm not going to dive more into that topic. With the changes of your foreach-loop the call should work and your view should be loaded.
You don't want something like a MainController that is always laoded, or at least not for those methods you have inside - May look up some tutorials on MVC. You only wanna load the controller for the specific section you're in.
Anyway, I wish you all the best for the future and happy coding! :)

PHP set parent class property works but subsequent if statement doesn't

I am building a genetics calculator, and have reduced my code to a simple format to explain my issue.
I basically have this line which instantiates a hatch object:
$hatch = new Hatch($maleGeneticsPOST, $femaleGeneticsPOST, 'leopardGecko', true);
This takes a form post for the parent genetics and sets the species type. Below is my Parent class and Child class to show how this essentially works:
class Genetics
{
public $species = '';
public $dominants = [];
public $recessives = [];
public $snows = [];
public $wildtypes = [];
function __construct($species)
{
$this->species = $species;
echo $species; // returns leopardGecko as expected
}
}
class Hatch extends Genetics
{
function __construct($father, $mother, $species, $autoHatch = true, $hatchMethod = "punnett")
{
parent::__construct($species);
// Other code for $father, $mother etc.
}
}
On the face of it, those 2 classes are working well with each other, I can set the species type in the object and Hatch will set the parent to it.
However, what I am struggling to do is to then use the $species property in the parent to set the genetics, based off of the species selected/set; here's an example:
class Genetics
{
public $species = '';
public $dominants = [];
public $recessives = [];
public $snows = [];
public $wildtypes = [];
function __construct($species)
{
$this->species = $species;
echo $species; // returns leopardGecko as expected
if($species === "leopardGecko"){
$this->dominants = ['NN', 'BB', 'TT'];
$this->recessives = ['Bb', 'Tt', 'Rr'];
$this->snows = ['Mm', 'Gg'];
$this->wildtypes = ['QQ', 'Qq'];
}
}
}
And when I try and use them further down in my Hatch class, they just return empty arrays:
foreach ($alleles as $allele) {
//echo $this->allGenetics[$allele].' ';
if (in_array($allele, $this->dominants, true)) {
//echo $this->allGenetics[$allele].' ';
array_push($geckoGenetics['Gecko']['Dominants'], $this->allGenetics[$allele]);
array_push($geckoGenetics['Gene']['Dominants'], $allele);
} elseif (in_array($allele, $this->recessives, true)) {
//echo $this->allGenetics[$allele].' ';
array_push($geckoGenetics['Gecko']['Recessives'], $this->allGenetics[$allele]);
array_push($geckoGenetics['Gene']['Recessives'], $allele);
} elseif (in_array($allele, $this->wildtypes, true)) {
//echo $this->allGenetics[$allele].' ';
array_push($geckoGenetics['Gecko']['Wildtypes'], $this->allGenetics[$allele]);
array_push($geckoGenetics['Gecko']['Recessives'], $this->allGenetics[$allele]);
array_push($geckoGenetics['Gene']['Wildtypes'], $allele);
array_push($geckoGenetics['Gene']['Recessives'], $allele);
} elseif (in_array($allele, $this->snows, true)) {
array_push($geckoGenetics['Gecko']['Snows'], $this->allGenetics[$allele]);
array_push($geckoGenetics['Gene']['Snows'], $allele);
}
}
Please note: The rest of that code works fine, I'm just talking about the $this->dominants, $this->recessives, $this->wildtypes & $this->snows variables - they return empty.
Am I missing something obvious? This is my first proper go at OOP and it's going well, apart from this bit!
'There is a difference in how you're calling the field $species and how you're trying to do so with $dominants. If you want to access fields outside of the scope of your function, you'll need to call them using $this->.
So in the constructor, if you replace the following:
public $dominants = ['NN', 'BB', 'TT'];
public $recessives = ['Bb', 'Tt', 'Rr'];
public $snows = ['Mm', 'Gg];
public $wildtypes = ['QQ', 'Qq'];
with:
$this->dominants = ['NN', 'BB', 'TT'];
$this->recessives = ['Bb', 'Tt', 'Rr'];
$this->snows = ['Mm', 'Gg'];
$this->wildtypes = ['QQ', 'Qq'];
It should work.

Cannot use object of type lang as array

I found a free PHP admin system script online which I have setup but can not get working.
I keep getting this error "Cannot use object of type lang as array"
and i'm not sure what this means.
The line of code that the error is on is part of a class which is here:
class lang {
public function __construct( $lang = false, $URL = '' ) {
}
private function storeAllowedLanguages() {
}
private function setLanguage($lang) {
}
public static function createButtons($ismobile) {
}
public static function translate($key, $ucfirst=false) {
if( !isset($_SESSION['LANG']) ) {
$DB = new db;
$sql = '
SELECT `key`, `value`
FROM `_adminlang`
WHERE `lang` = "en"
';
$res = $DB->fetch( $sql );
foreach($res as $rec) {
$_SESSION['LANG'][$rec['key']] = $rec['value'];
}
}
return isset($_SESSION['LANG'][$key]) ? $_SESSION['LANG'][$key] : ucfirst(str_replace('_', ' ', strtolower($key)));
}
}
and the actual line is :
return isset($_SESSION['LANG'][$key]) ? $_SESSION['LANG'][$key] : ucfirst(str_replace('_', ' ', strtolower($key)));
could someone help me out with this error please im very stuck
$_SESSION['LANG'] is most likely a object.. try
$_SESSION['LANG']->$key

Error When Calling Function

I searched forever trying to find an answer, but was ultimately stumped. I've been writing code to allow multiple bots to connect to a chat box. I wrote all the main code and checked it over to make sure it was all okay. Then when I got to calling the function needed to make it work, it gave me an error saying:
Notice: Undefined variable: ip in C:\wamp\www\BotRaid.php on line 40
And also an error saying:
Fatal Error: Cannot access empty property in C:\wamp\www\BotRaid.php
on line 40
( Also a screenshot here: http://prntscr.com/ckz55 )
<?php
date_default_timezone_set("UCT");
declare(ticks=1);
set_time_limit(0);
class BotRaid
{
public $ip="174.36.242.26";
public $port=10038;
public $soc = null;
public $packet = array();
##############################
# You can edit below this #
##############################
public $roomid="155470742";
public $userid = "606657406";
public $k = "2485599605";
public $name="";
public $avatar=;
public $homepage="";
##############################
# Stop editing #
##############################
public function retry()
{
$this->connect($this->$ip,$this->$port); //Line 40, where I'm getting the error now.
$this->join($this->$roomid);
while($this->read()!="DIED");
}
public function connect($ip, $port)
{
if($this->$soc!=null) socket_close($this->$soc);
$soc = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
if(!$this->$soc)$this->port();
if(!socket_connect($this->$soc,$this->$ip,$this->$port))$this->port();
}
public function port()
{
$this->$port++;
if($this->$port>10038) $this->$port=10038;
$this->retry();
}
public function join($roomid)
{
$this->send('<y m="1" />');
$this->read();
$this->send('<j2 q="1" y="'.$this->$packet['y']['i'].'" k="'.$this->$k.'" k3="0" z="12" p="0" c"'.$roomid.'" f="0" u="'.$this->$userid.'" d0="0" n="'.$this->$name.'" a="'.$this->$avatar.'" h="'.$this->$homepage.'" v="0" />');
$this->port();
$this->$roomid;
}
public function send($msg)
{
echo "\n Successfully connected.";
socket_write($this->$soc, $this->$msg."\0", strlen($this->$msg)+1);
}
public function read($parse=true)
{
$res = rtrim(socket_read($this->$soc, 4096));
echo "\nSuccessfully connected.";
if(strpos(strtolower($res), "Failed"))$this->port();
if(!$res) return "DIED";
$this->lastPacket = $res;
if($res{strlen($res)-1}!='>') {$res.=$this->read(false);}
if($parse)$this->parse($res);
return $res;
}
public function parse($packer)
{
$packet=str_replace('+','#più#',str_replace(' ="',' #=#"',$packet));
if(substr_count($packet,'>')>1) $packet = explode('/>',$packet);
foreach((Array)$packet as $p) {
$p = trim($p);
if(strlen($p)<5) return;
$type = trim(strtolower(substr($p,1,strpos($p.' ',' '))));
$p = trim(str_replace("<$type",'',str_replace('/>','',$p)));
parse_str(str_replace('"','',str_replace('" ','&',str_replace('="','=',str_replace('&','__38',$p)))),$this->packet[$type]);
foreach($this->packet[$type] as $k=>$v) {
$this->packet[$type][$k] = str_replace('#più#','+',str_replace('#=#','=',str_replace('__38','&',$v)));
}
}
}
}
$bot = new BotRaid; //This is where I had the error originally
$bot->retry();
?>
Line 40 is below the "Stop Editing" line. Anyone have any suggestions? Or perhaps need me to clear some things up?
You are accessing the properties of the class incorrectly.
The line:
$this->connect($this->$ip,$this->$port);
Should be:
$this->connect($this->ip, $this->port);
Since there was no local variable called $ip, your expression was evaluating to $this-> when trying to access the property since PHP lets you access properties and functions using variables.
For example, this would work:
$ip = 'ip';
$theIp = $this->$ip; // evaluates to $this->ip
// or a function call
$method = 'someFunction';
$value = $this->$method(); // evaluates to $this->someFunction();
You will have to change all the occurrences of $this->$foo with $this->foo since you used that notation throughout the class.
As noted in the comment by #Aatch, see the docs on variable variables for further explanation. But that is what you were running into accidentally.

Why is this Zend Framework _redirect() call failing?

I am developing a Facebook app in Zend Framework. In startAction() I am getting the following error:
The URL http://apps.facebook.com/rails_across_europe/turn/move-trains-auto is not valid.
I have included the code for startAction() below. I have also included the code for moveTrainsAutoAction (these are all TurnController actions) I can't find anything wrong with my _redirect() in startAction(). I am using the same redirect in other actions and they execute flawlessly. Would you please review my code and let me know if you find a problem? I appreciate it! Thanks.
public function startAction() {
require_once 'Train.php';
$trainModel = new Train();
$config = Zend_Registry::get('config');
require_once 'Zend/Session/Namespace.php';
$userNamespace = new Zend_Session_Namespace('User');
$trainData = $trainModel->getTrain($userNamespace->gamePlayerId);
switch($trainData['type']) {
case 'STANDARD':
default:
$unitMovement = $config->train->standard->unit_movement;
break;
case 'FAST FREIGHT':
$unitMovement = $config->train->fast_freight->unit_movement;
break;
case 'SUPER FREIGHT':
$unitMovement = $config->train->superfreight->unit_movement;
break;
case 'HEAVY FREIGHT':
$unitMovement = $config->train->heavy_freight->unit_movement;
break;
}
$trainRow = array('track_units_remaining' => $unitMovement);
$where = $trainModel->getAdapter()->quoteInto('id = ?', $trainData['id']);
$trainModel->update($trainRow, $where);
$this->_redirect($config->url->absolute->fb->canvas . '/turn/move-trains-auto');
}
.
.
.
public function moveTrainsAutoAction() {
$log = Zend_Registry::get('log');
$log->debug('moveTrainsAutoAction');
require_once 'Train.php';
$trainModel = new Train();
$userNamespace = new Zend_Session_Namespace('User');
$gameNamespace = new Zend_Session_Namespace('Game');
$trainData = $trainModel->getTrain($userNamespace->gamePlayerId);
$trainRow = $this->_helper->moveTrain($trainData['dest_city_id']);
if(count($trainRow) > 0) {
if($trainRow['status'] == 'ARRIVED') {
// Pass id for last city user selected so we can return user to previous map scroll postion
$this->_redirect($config->url->absolute->fb->canvas . '/turn/unload-cargo?city_id='.$gameNamespace->endTrackCity);
} else if($trainRow['track_units_remaining'] > 0) {
$this->_redirect($config->url->absolute->fb->canvas . '/turn/move-trains-auto');
} else { /* Turn has ended */
$this->_redirect($config->url->absolute->fb->canvas . '/turn/end');
}
}
$this->_redirect($config->url->absolute->fb->canvas . '/turn/move-trains-auto-error'); //-set-destination-error');
}
As #Jani Hartikainen points out in his comment, there is really no need to URL-encode underscores. Try to redirect with literal underscores and see if that works, since I believe redirect makes some url encoding of its own.
Not really related to your question, but in my opinion you should refactor your code a bit to get rid of the switch-case statements (or at least localize them to a single point):
controllers/TrainController.php
[...]
public function startAction() {
require_once 'Train.php';
$trainTable = new DbTable_Train();
$config = Zend_Registry::get('config');
require_once 'Zend/Session/Namespace.php';
$userNamespace = new Zend_Session_Namespace('User');
$train = $trainTable->getTrain($userNamespace->gamePlayerId);
// Add additional operations in your getTrain-method to create subclasses
// for the train
$trainTable->trackStart($train);
$this->_redirect(
$config->url->absolute->fb->canvas . '/turn/move-trains-auto'
);
}
[...]
models/dbTable/Train.php
class DbTable_Train extends Zend_Db_Table_Abstract
{
protected $_tableName = 'Train';
[...]
/**
*
*
* #return Train|false The train of $playerId, or false if the player
* does not yet have a train
*/
public function getTrain($playerId)
{
// Fetch train row
$row = [..];
return $this->trainFromDbRow($row);
}
private function trainFromDbRow(Zend_Db_Table_Row $row)
{
$data = $row->toArray();
$trainType = 'Train_Standard';
switch($row->type) {
case 'FAST FREIGHT':
$trainType = 'Train_Freight_Fast';
break;
case 'SUPER FREIGHT':
$trainType = 'Train_Freight_Super';
break;
case 'HEAVY FREIGHT':
$trainType = 'Train_Freight_Heavy';
break;
}
return new $trainType($data);
}
public function trackStart(Train $train)
{
// Since we have subclasses here, polymorphism will ensure that we
// get the correct speed etc without having to worry about the different
// types of trains.
$trainRow = array('track_units_remaining' => $train->getSpeed());
$where = $trainModel->getAdapter()->quoteInto('id = ?', $train->getId());
$this->update($trainRow, $where);
}
[...]
/models/Train.php
abstract class Train
{
public function __construct(array $data)
{
$this->setValues($data);
}
/**
* Sets multiple values on the model by calling the
* corresponding setter instead of setting the fields
* directly. This allows validation logic etc
* to be contained in the setter-methods.
*/
public function setValues(array $data)
{
foreach($data as $field => $value)
{
$methodName = 'set' . ucfirst($field);
if(method_exists($methodName, $this))
{
$this->$methodName($value);
}
}
}
/**
* Get the id of the train. The id uniquely
* identifies the train.
* #return int
*/
public final function getId ()
{
return $this->id;
}
/**
* #return int The speed of the train / turn
*/
public abstract function getSpeed ();
[..] //More common methods for trains
}
/models/Train/Standard.php
class Train_Standard extends Train
{
public function getSpeed ()
{
return 3;
}
[...]
}
/models/Train/Freight/Super.php
class Train_Freight_Super extends Train
{
public function getSpeed ()
{
return 1;
}
public function getCapacity ()
{
return A_VALUE_MUCH_LARGER_THAN_STANDARD;
}
[...]
}
By default, this will send an HTTP 302 Redirect. Since it is writing headers, if any output is written to the HTTP output, the program will stop sending headers. Try looking at the requests and response inside Firebug.
In other case, try using non default options to the _redirect() method. For example, you can try:
$ropts = { 'exit' => true, 'prependBase' => false };
$this->_redirect($config->url->absolute->fb->canvas . '/turn/move-trains-auto', $ropts);
There is another interesting option for the _redirect() method, the code option, you can send for example a HTTP 301 Moved Permanently code.
$ropts = { 'exit' => true, 'prependBase' => false, 'code' => 301 };
$this->_redirect($config->url->absolute->fb->canvas . '/turn/move-trains-auto', $ropts);
I think I may have found the answer. It appears that Facebook does not play nice with redirect, so it is neccessary to use Facebook's 'fb:redirect' FBML. This appears to work:
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender();
echo '<fb:redirect url="' . $config->url->absolute->fb->canvas . '/turn/move-trains-auto"/>';

Categories