简体   繁体   English

PhpStorm-索引文件不存在错误

[英]PhpStorm - Index file doesn't exist error

I am trying to familiarize myself with PHP and PhpStorm. 我正在尝试使自己熟悉PHP和PhpStorm。 When I try to run any PHP file it gives me following error: 当我尝试运行任何PHP文件时,出现以下错误:

404 Not Found: Index file doesn't exist. 找不到404:索引文件不存在。

And when I try to execute my PHP code via small HTML code then it doesn't stop at breakpoint. 当我尝试通过小的HTML代码执行我的PHP代码时,它不会在断点处停止。

Is there a config which I am missing? 有没有我所缺少的配置?

HTML: HTML:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>

<h1>message</h1>

<form action="http://pushchat.local:44447/api.php" method="post">

user_id: <input type="text" name="user_id" value="1234567890123456789012345678901234567890"/><br/>
text: <textarea name="text">Hello, world!</textarea><br/>
<br/>
<input type="hidden" name="cmd" value="message"/>
<input type="submit" value="Submit"/>

</form>

</body>
</html>

PHP: PHP:

<?php

// This is the server API for the PushChat iPhone app. To use the API, the app
// sends an HTTP POST request to our URL. The POST data contains a field "cmd"
// that indicates what API command should be executed.

try
{
    // Are we running in development or production mode? You can easily switch
    // between these two in the Apache VirtualHost configuration.
    if (!defined('APPLICATION_ENV'))
        define('APPLICATION_ENV', getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production');

    // In development mode, we show all errors because we obviously want to 
    // know about them. We don't do this in production mode because that might
    // expose critical details of our app or our database. Critical PHP errors
    // will still be logged in the PHP and Apache error logs, so it's always
    // a good idea to keep an eye on them.
    if (APPLICATION_ENV == 'development')
    {
        error_reporting(E_ALL|E_STRICT);
        ini_set('display_errors', 'on');
    }
    else
    {
        error_reporting(0);
        ini_set('display_errors', 'off');
    }

    // Load the config file. I prefer to keep all configuration settings in a
    // separate file so you don't have to mess around in the main code if you
    // just want to change some settings.
    require_once 'api_config.php';
    $config = $config[APPLICATION_ENV];

    // In development mode, we fake a delay that makes testing more realistic.
    // You're probably running this on a fast local server but in production
    // mode people will be using it on a mobile device over a slow connection.
    if (APPLICATION_ENV == 'development')
        sleep(2);

    // To keep the code clean, I put the API into its own class. Create an
    // instance of that class and let it handle the request.
    $api = new API($config);
    $api->handleCommand();

    echo "OK" . PHP_EOL;
}
catch (Exception $e)
{
    // The code throws an exception when something goes horribly wrong; e.g.
    // no connection to the database could be made. In development mode, we
    // show these exception messages. In production mode, we simply return a
    // "500 Server Error" message.

    if (APPLICATION_ENV == 'development')
        var_dump($e);
    else
        exitWithHttpError(500);
}

////////////////////////////////////////////////////////////////////////////////

function exitWithHttpError($error_code, $message = '')
{
    switch ($error_code)
    {
        case 400: header("HTTP/1.0 400 Bad Request"); break;
        case 403: header("HTTP/1.0 403 Forbidden"); break;
        case 404: header("HTTP/1.0 404 Not Found"); break;
        case 500: header("HTTP/1.0 500 Server Error"); break;
    }

    header('Content-Type: text/plain');

    if ($message != '')
        header('X-Error-Description: ' . $message);

    exit;
}

function isValidUtf8String($string, $maxLength, $allowNewlines = false)
{
    if (empty($string) || strlen($string) > $maxLength)
        return false;

    if (mb_check_encoding($string, 'UTF-8') === false)
        return false;

    // Don't allow control characters, except possibly newlines 
    for ($t = 0; $t < strlen($string); $t++)
    {
        $ord = ord($string{$t});

        if ($allowNewlines && ($ord == 10 || $ord == 13))
            continue;

        if ($ord < 32)
            return false;
    }

    return true;
}

function truncateUtf8($string, $maxLength)
{
    $origString = $string;
    $origLength = $maxLength;

    while (strlen($string) > $origLength)
    {
        $string = mb_substr($origString, 0, $maxLength, 'utf-8');
        $maxLength--;
    }

    return $string;
}

////////////////////////////////////////////////////////////////////////////////

class API
{
    // Because the payload only allows for 256 bytes and there is some overhead
    // we limit the message text to 190 characters.
    const MAX_MESSAGE_LENGTH = 190;

    private $pdo;

    function __construct($config)
    {
        // Create a connection to the database.
        $this->pdo = new PDO(
            'mysql:host=' . $config['db']['host'] . ';dbname=' . $config['db']['dbname'], 
            $config['db']['username'], 
            $config['db']['password'],
            array());

        // If there is an error executing database queries, we want PDO to
        // throw an exception. Our exception handler will then exit the script
        // with a "500 Server Error" message.
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // We want the database to handle all strings as UTF-8.
        $this->pdo->query('SET NAMES utf8');
    }

    function handleCommand()
    {
        // Figure out which command the client sent and let the corresponding
        // method handle it. If the command is unknown, then exit with an error
        // message.
        if (isset($_POST['cmd']))
        {
            switch (trim($_POST['cmd']))
            {
                case 'join': $this->handleJoin(); return;
                case 'leave': $this->handleLeave(); return;
                case 'update': $this->handleUpdate(); return;
                case 'message': $this->handleMessage(); return;
            }
        }

        exitWithHttpError(400, 'Unknown command');
    }

    // The "join" API command registers a user to receive notifications that
    // are sent in a specific "chat room". Each chat room is identified by a
    // secret code. All the users who register with the same secret code can
    // see each other's messages.
    //
    // This command takes the following POST parameters:
    //
    // - user_Id:  A unique identifier. Must be a string of 40 hexadecimal characters.
    // - token: The device's device token. Must be a string of 64 hexadecimal
    //          characters, or "0" if no token is available yet.
    // - name:  The nickname of the user. Must be a UTF-8 string of maximum 255
    //          bytes. Only the first 20 bytes are actually shown in the push 
    //          notifications.
    // - code:  The secret code that identifies the chat room. Must be a UTF-8
    //          string of maximum 255 bytes.
    //
    function handleJoin()
    {
        $userId = $this->getUserId();
        $token = $this->getDeviceToken(true);
        $name = $this->getString('name', 255);
        $code = $this->getString('code', 255);

        // When the client sends a "join" command, we add a new record to the
        // active_users table. We identify the client by the user_id that it
        // provides. When the client sends a "leave" command, we delete its
        // record from the active_users table.

        // It is theoretically possible that a client sends a "join" command
        // while its user_id is still present in active_users (because it did not
        // send a "leave" command). In that case, we simply remove the old
        // record first and then insert the new one.

        $this->pdo->beginTransaction();

        $stmt = $this->pdo->prepare('DELETE FROM active_users WHERE user_Id = ?');
        $stmt->execute(array($userId));

        $stmt = $this->pdo->prepare('INSERT INTO active_users (user_Id, device_token, nickname, secret_code, ip_address) VALUES (?, ?, ?, ?, ?)');
        $stmt->execute(array($userId, $token, $name, $code, $_SERVER['REMOTE_ADDR']));

        $this->pdo->commit();
    }

    // The "leave" API command removes a user from a chat room. That user will
    // no longer receive push notifications for messages sent to that room.
    //
    // This command takes the following POST parameters:
    //
    // - user_id: A unique identifier. Must be a string of 40 hexadecimal characters.
    //
    function handleLeave()
    {
        $userId = $this->getUserId();
        $stmt = $this->pdo->prepare('DELETE FROM active_users WHERE user_Id = ?');
        $stmt->execute(array($userId));
    }

    // The "update" API command gives a user a new device token.
    //
    // This command takes the following POST parameters:
    //
    // - user_id:  A unique identifier. Must be a string of 40 hexadecimal characters.
    // - token: The device's device token. Must be a string of 64 hexadecimal
    //          characters.
    //
    function handleUpdate()
    {
        $userId = $this->getUserId();
        $token = $this->getDeviceToken(false);
        $stmt = $this->pdo->prepare('UPDATE active_users SET device_token = ? WHERE user_Id = ?');
        $stmt->execute(array($token, $userId));
    }

    // The "message" API command sends a message to all users who are registered
    // with the same secret code as the sender of the message.
    //
    // This command takes the following POST parameters:
    //
    // - user_id: A unique identifier. Must be a string of 40 hexadecimal characters.
    // - text: The message text. Must be a UTF-8 string of maximum 190 bytes.
    //
    function handleMessage()
    {
        $userId = $this->getUserId();
        $text = $this->getString('text', self::MAX_MESSAGE_LENGTH, true);

        // First, we get the record for the sender of the message from the
        // active_users table. That gives us the nickname, device token, and
        // secret code for that user.

        $stmt = $this->pdo->prepare('SELECT * FROM active_users WHERE user_Id = ? LIMIT 1');
        $stmt->execute(array($userId));
        $user = $stmt->fetch(PDO::FETCH_OBJ);

        if ($user !== false)
        {
            // Put the sender's name and the message text into the JSON payload
            // for the push notification.
            $payload = $this->makePayload($user->nickname, $text);

            // Find the device tokens for all other users who are registered
            // for this secret code. We exclude the device token of the sender
            // of the message, so he will not get a push notification. We also
            // exclude users who have not submitted a valid device token yet.
            $stmt = $this->pdo->prepare("SELECT device_token FROM active_users WHERE secret_code = ? AND device_token <> ? AND device_token <> '0'");
            $stmt->execute(array($user->secret_code, $user->device_token));
            $tokens = $stmt->fetchAll(PDO::FETCH_COLUMN);

            // Send out a push notification to each of these devices.
            foreach ($tokens as $token)
            {
                $this->addPushNotification($token, $payload);
            }
        }
    }

    // Retrieves the user identifier from the POST data. If the user_id does not
    // appear to be valid, the script exits with an error message.
    function getUserId()
    {
        if (!isset($_POST['user_id']))
            exitWithHttpError(400, 'Missing user_id');

        $userId = trim(urldecode($_POST['user_id']));
        if (!$this->isValidUserId($userId))
            exitWithHttpError(400, 'Invalid user_id');

        return $userId;
    }

    // Checks whether the format of the user identifier is correct (40 hex
    // characters or 32 for the simulator).
    function isValidUserId($userId)
    {
        if (strlen($userId) != 40 && strlen($userId) != 32)  // 32 for simulator
            return false;

        if (preg_match("/^[0-9a-fA-F]+$/", $userId) == 0)
            return false;

        return true;
    }

    // Retrieves the device token from the POST data. If the token does not
    // appear to be valid, the script exits with an error message.
    function getDeviceToken($mayBeEmpty = false)
    {
        if (!isset($_POST['token']))
            exitWithHttpError(400, 'Missing device token');

        $token = trim($_POST['token']);

        // The "join" command allows a token value of "0" to be specified,
        // which is necessary in case the client did not yet obtain a device
        // token at that point. We allow such clients to join, but they will
        // not receive any notifications until they provide a valid token
        // using the "update" command.
        if ($mayBeEmpty && $token == "0")
            return $token;

        if (!$this->isValidDeviceToken($token))
            exitWithHttpError(400, 'Invalid device token');

        return $token;  
    }

    // Checks whether the format of the device token is correct (64 hexadecimal
    // characters). Note: we have no means to verify whether the device token
    // was really issued by APNS and corresponds to an actual device.
    function isValidDeviceToken($deviceToken)
    {
        if (strlen($deviceToken) != 64)
            return false;

        if (preg_match("/^[0-9a-fA-F]{64}$/", $deviceToken) == 0)
            return false;

        return true;
    }

    // Looks in the POST data for a field with the given name. If the field
    // is not a valid UTF-8 string, or it is too long, the script exits with
    // an error message.
    function getString($name, $maxLength, $allowNewlines = false)
    {
        if (!isset($_POST[$name]))
            exitWithHttpError(400, "Missing $name");

        $string = trim($_POST[$name]);
        if (!isValidUtf8String($string, $maxLength, $allowNewlines))
            exitWithHttpError(400, "Invalid $name");

        return $string;
    }

    // Creates the JSON payload for the push notification message. The "alert"
    // text has the following format: "sender_name: message_text". Recipients
    // can obtain the name of the sender by parsing the alert text up to the
    // first colon followed by a space.
    function makePayload($senderName, $text)
    {
        // Convert the nickname of the sender to JSON and truncate to a maximum
        // length of 20 bytes (which may be less than 20 characters).
        $nameJson = $this->jsonEncode($senderName);
        $nameJson = truncateUtf8($nameJson, 20);

        // Convert and truncate the message text
        $textJson = $this->jsonEncode($text);
        $textJson = truncateUtf8($textJson, self::MAX_MESSAGE_LENGTH);

        // Combine everything into a JSON string
        $payload = '{"aps":{"alert":"' . $nameJson . ': ' . $textJson . '","sound":"default"}}';
        return $payload;
    }

    // We don't use PHP's built-in json_encode() function because it converts
    // UTF-8 characters to \uxxxx. That eats up 6 characters in the payload for
    // no good reason, as JSON already supports UTF-8 just fine.
    function jsonEncode($text)
    {
        static $from = array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"');
        static $to = array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"');
        return str_replace($from, $to, $text);
    }

    // Adds a push notification to the push queue. The notification will not
    // be sent immediately. The server runs a separate script, push.php, which 
    // periodically checks for new entries in this database table and sends
    // them to the APNS servers.
    function addPushNotification($deviceToken, $payload)
    {
        // Payloads have a maximum size of 256 bytes. If the payload is too
        // large (which shouldn't happen), we won't send this notification.
        if (strlen($payload) <= 256)
        {
            $stmt = $this->pdo->prepare('INSERT INTO push_queue (device_token, payload, time_queued) VALUES (?, ?, NOW())');
            $stmt->execute(array($deviceToken, $payload));
        }
    }
}

Recently i faced the similar problem. 最近,我遇到了类似的问题。 In fact phpstorm is able to open files by two ways: 实际上,phpstorm可以通过两种方式打开文件:

  1. First create/open project and then open files within the project (this is the prefered way) 首先创建/打开项目,然后在项目中打开文件(这是首选方式)
  2. Opening external files 打开外部文件

To open an external file do one of the following: 要打开外部文件,请执行以下任一操作:

Choose File | 选择文件| Open on the main menu and select the desired file in the dialog box that opens. 在主菜单上打开,然后在打开的对话框中选择所需的文件。 Drag the required file from the Explorer (Windows), File Browser (Linux), or Finder (OS) and drop it to the editor. 将所需的文件从资源管理器(Windows),文件浏览器(Linux)或Finder(OS)中拖放到编辑器中。 The file will open for editing in a new tab. 该文件将打开,以便在新选项卡中进行编辑。

So if you open your files using the first way (through project) you shouldn't face the "404 Not Found: Index file doesn't exist." 因此,如果您通过第一种方式(通过项目)打开文件,则不会遇到“找不到404:索引文件不存在”的问题。 problem. 问题。

But when i use the second one (Opening external files) i see the same problem. 但是当我使用第二个(打开外部文件)时,我看到了同样的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM