PHP Error

Hello everyone,

I’m new to Yii framework. Very much interested to try out my first application. When I ran it onto local(win32) system it worked. But on my host, which is unix it is giving following error for both contact and login page controllers. This is the default structure which gets created by yiic tool.

Is there anywhere I’m going wrong?

Please help.

PHP Error is as follows:

YiiBase::include(ContactForm.php) [<a href=‘yiibase.include’>yiibase.include</a>]: failed to open stream: No such file or directory

Stack Trace

#0 /WebRoot/MySite/protected/frameworks/Yii/YiiBase.php(316): autoload()

#1 unknown(0): autoload()

#2 /WebRoot/MySite/protected/controllers/SiteController.php(36): spl_autoload_call()

#3 /WebRoot/MySite/protected/frameworks/Yii/web/actions/CInlineAction.php(32): SiteController->actionContact()

#4 /WebRoot/MySite/protected/frameworks/Yii/web/CController.php(300): CInlineAction->run()

#5 /WebRoot/MySite/protected/frameworks/Yii/web/CController.php(278): SiteController->runAction()

#6 /WebRoot/MySite/protected/frameworks/Yii/web/CController.php(257): SiteController->runActionWithFilters()

#7 /WebRoot/MySite/protected/frameworks/Yii/web/CWebApplication.php(332): SiteController->run()

#8 /WebRoot/MySite/protected/frameworks/Yii/web/CWebApplication.php(120): CWebApplication->runController()

#9 /WebRoot/MySite/protected/frameworks/Yii/base/CApplication.php(133): CWebApplication->processRequest()

#10 /WebRoot/MySite/index.php(11): CWebApplication->run()

That is because windows doens’t care about case sensivity, but *nix do.

In windows contactform.php == ContactForm.php

In *nix contactform.php != ContactForm.php

Check if you file(s) are named correctly

http://www.yiiframework.com/doc/guide/basics.convention#file

I know, on *nix it is case sensitive. I have file names Camel form. I have created those files using yiic command line tool. And I have checked following :

File name ContactForm.php, class name ContactForm

views/layouts/main.php - array(‘label’=>‘Contact’, ‘url’=>array(’/site/contact’))

and in SiteController.php I’m using if(isset($_POST[‘ContactForm’])) this way.

This is all automatically generated code. Where to look for a problem solution?

Edit: I also tried printing $className in autoload() function. It prints "ContactForm" which is same as the filename in protected/models folder.

yii provides a requirements check

make sure your webspace can handle yii

PDO, memcache, Mcrypt , soap are missing. But I guess that won’t affect a basic application right?

PDO will.

At least if you try to access some sort of database. Although you could of course use the methods provided by PHP (mysql_connect, …) you won’t be able to use the features yii provides (active records, …).

This example that does not run, is this the plain example application as described here?

If autoloading doesn’t work, I can see 3 points that need to be checked:

[list=1]

[*]class names and file names in correct upper/lower case?

[*]pathname containing the file in include list (use Yii::import)?

[*]are there other autoloaders registered that might trow exceptions?

[/list]

  1. I checked the classes names. They are automatically generated by yiic. They are fine.

class names and file names are correct.

  1. I did not get the meaning of this one.

  2. No

It is the same code which gets generated by yiic. So, I think, web interface for yiic will be helpful in this case.

I think, Command line version generates os specific code.

The basic structure do not use PDO, so I think it won’t be the problem in this case.

The autoload implementation yii provides only searches specific folders for files that might need to be included. If the whole application you’re trying to run has been generated by the yiic tool, this shouldn’t be a problem. But let’s say you created an own folder “protected/myClasses” and put your contact form there, yii wouldn’t be able to autoload it, because it would not search within that folder. You could either include it from your configuration…

protected/config/main.php




  [...]

  // preloading 'log' component

  'preload'=>array('log'),


  // autoloading model and component classes

  'import'=>array(

    'application.models.*',

    'application.models.enums.*', //guess I added this one some time ago, the other two seem to be standard

    'application.components.*',

  ),


  // application components

  'components'=>array(

  [...]



… or you might add such search pathes somewhere in your code. For example, I have a controller that uses models that aren’t used somewhere else in my code. So I added the path containing those models in the controller file rather than in the config:




<?php


Yii::import('application.models.tool.parser.*');


class ParserController extends ToolBaseController

{


[...]



Thanks for explaining to me. But, I have created all files using yiic and just uploaded to hosting without any changes. Just for testing purpose if Yii works for me on that host. There is no change in files.

Is there anything more required to check? probably something server dependent! I have digged and found my host is using apache 1.* + php 5.2.6 Is it the issue?

Edit:

To check if operating system is issue or not, I created files using yiic on *nix system and uploaded. But the same issue.

index.php?r=site/index page works fine, while index.php?r=site/contact and index.php?r=site/login doesn’t work.

Hm, you might check if you have privileges to override php settings. I’m not absolutely sure, but I think one can restrict the use of functions like set_include_path (which is used by yii). So simply run a little test script on your host with something like:




$path = 'path/you/want/beeing/added';

$okay = set_include_path( get_include_path() .PATH_SEPARATOR . $path );


if( $okay === false )

  echo "set_include_path does not work";

else

  echo "set_include_path works";



"set_include_path does not work" !!

Yes my host is not supporting it. What is the fix then?

I would suggest to search for another host. ;)

But you could also try to write your own or extend yiis autoload implementation. Traverse files in a folder if the Yii::import ends with "*" and add them to the _classes member instead of adding the path to the include_path might work.

Ok, some information I gathered more… here is what host has to say!

“User relative paths (ones that do not start with /) or it won’t work!”

I think, everywhere Yii uses /paths

Is this also a problem?

I will try extending yii’s autoload implementation. I’m still not quite sure how though!

Edit: I guess, I will need to change YiiBase::import() method since it has the set_include_path() . If I use another method to store the aliases like arrays or similar, will it work? Or is there any better solution?

Hi,

I have am working on a project in Yii and it has been working fine now I got this PHP Error all of sudden. Framework fails to load this file which I don’t have in my framework nor I tried to add it anywhere.


include(SideLinkItem.php) [<a href='function.include'>function.include</a>]: failed to open stream: No such file or directory

Finally I figured out, my server not supporting get_include_path() and set_include_path() methods!! Admin says, it does, but I get no output set.

So, I figured those methods are used in import() of YiiBase class.

So, I tried with extending yii’s import method like this in Yii class




class Yii extends YiiBase

{

	public static function import($alias,$forceInclude=false)

	{

		Yii::import($alias,$forceInclude);

	}

}



Which gives this error.


Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 261900 bytes) in "dir\name"



I also tried this way




class Yii extends YiiBase

{

	public static function import($alias,$forceInclude=false)

	{

		parent::import($alias,$forceInclude);

	}

}



which gave following error.


Fatal error: Class name must be a valid object or a string in "dir\name"

Please help me how to override the method and call the regular implementation first and then my own code which will traverse directory and add it to some variable ( i think its $_classes, but it is private! ) so please help.

Sharing my code for the situation:

When set_include_path or get_include_path is disabled.




public static function import($alias,$forceInclude=false)

	{

.....

else  // a directory

{

  if(self::$_includePaths===null)

  {

    self::$_includePaths=array_unique(explode(PATH_SEPARATOR,get_include_path()));

    if(($pos=array_search('.',self::$_includePaths,true))!==false)

	unset(self::$_includePaths[$pos]);

  }

  // Modified {Start}

  if( empty($_includePaths) )

  {

    foreach(glob($path.DIRECTORY_SEPARATOR.'*.php') as $szFilename)

    {

	$fileName = explode('.',basename($szFilename));

	self::$_imports[$fileName[0]]=$szFilename;

	if($forceInclude)

          require($szFilename);

	else

	  self::$_classes[$fileName[0]]=$szFilename;

    }

  }

  // Modified {End}

  array_unshift(self::$_includePaths,$path);

  set_include_path('.'.PATH_SEPARATOR.implode(PATH_SEPARATOR,self::$_includePaths));

  return self::$_imports[$alias]=$path;

}



I modified YiiBase class’s import method for directory include code.

Hope it helps who has similar problem as mine.

Hi. Thanks for your help thus far. I have the same problem, one host does not allow these php functions.

I have a php error when I run your fix :

Invalid argument supplied for foreach()

The basic structure most certainly does use PDO. The generated webapp uses the SqlLite <projectname>.db database stored in the protected/data directory. To access the table, the PDO extension (data abstraction library) and PDO SqlLite extension (PDO SqlLite driver) need to be enabled in your php.ini file. The Login model accesses a table in the database for storing user information. If SqlLite is not available on your server, you need to change the DSN in your main.php to use mysql or whatever database server you have available and also enable the PDO extension for that database server (something like pdo_mysql.so on a *nix server).

Is your Unix server running PHP 5.1 or later?