Asked  2 Years ago    Answers:  5   Viewed   97 times

I am designing my own MVC pattern to ease the process of creating homepages. My templating system needs my controller class to output my views. This means I have to output the file through a php function. I have been searching for some a while now and can't seem to find a solution.

How can I, through a PHP function, run a string representing some source code ("< ?", "< ?php", "? >" and so on) as php? Eval would not take my < ? signs (and I read that function is crap for some reason).

 Answers

2

You could execute the php code and collect the output like this:

ob_start();
include "template.phtml";
$out1 = ob_get_clean();

http://www.php.net/manual/de/function.ob-get-contents.php

Thursday, November 10, 2022
 
2

You are going in the wrong way about solving this.

Instead of each time manually making a new "Model" and then configuring it, you should create a structure that does it for you ( extremely simplified version ):

class ModelFactory
{
    protected $connection = null;
    // --- snip --

    public function __construct( $connection )
    {
        $this->connection = $connection;
    }
    // --- snip --

    public function buildMapper( $name )
    {
        $instance = new {$name}( $this->connection );
        return $instance;
    }
    // --- snip --

}

This class you would be using in index.php or bootstrap.php , or any other file you use as entry point for your application:

// at the bootstrap level
$modelFactory = new ModelFactory( new PDO(...) );

// i am assuming that you could get $controllerName 
// and $action from routing mechanism
$controller = new {$controllerName}( $modelFactory );
$controller->{$action}();

The main problem you have is actually cause by misunderstanding what Model is. In a proper MVC the Model is a layer, and not a specific class. Model layer is composed from multitude of class/instances with two major responsibilities:

  • domain business logic
  • data access and storage

The instances in first group are usually called Domain Objects or Business Objects (kinda like situation with geeks and nerds). They deal with validations, computation, different conditions, but have no clue how and where information is stored. It does not change how you make an Invoice , whether data comes from SQL, remote REST API or a screenshot of MS Word document.

Other group consists mostly of Data Mappers. They store and retrieve information from Domain Objects. This is usually where your SQL would be. But mappers do not always map directly to DB schema. In a classic many-to-many structure you might have either 1 or 2 or 3 mappers servicing the storage. Mappers usually one per each Domain Object .. but even that is not mandatory.

In a controller it would all look something like this.

public function actionFooBar()
{
    $mapper = $this->modelFactory->buildMapper( 'Book' );
    $book = $this->modelFactory->buildObject( 'Book' );
    $patron = $this->modelFactory->buildObject( 'Patron' );

    $book->setTitle('Neuromancer');
    $mapper->fetch( $book );

    $patron->setId( $_GET['uid']);

    if ( $book->isAvailable() )
    {
        $book->lendTo( $user );
    }

    $mapper->store( $book );

}

Maybe this will give you some indications for the direction in which to take it.

Some additional video materials:

  • Advanced OO Patterns (slides)
  • Global State and Singletons
  • Don't Look For Things!
Tuesday, August 16, 2022
 
4

Edit: And just when you think you have it all figured out you realise that there is a better way. Check out http://haacked.com/archive/2010/07/16/uploading-files-with-aspnetmvc.aspx

Original: I am not sure that I understand your question 100%, but I assume that you want to upload a file to a url that looks something like http://{server name}/{Controller}/Upload? This would be implemented exactly like a normal file upload using web forms.

So your controller has an action named upload and looks similar to this:

//For MVC ver 2 use:
[HttpPost]
//For MVC ver 1 use:
//[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Upload()
{
    try
    {
        foreach (HttpPostedFile file in Request.Files)
        {
            //Save to a file
            file.SaveAs(Path.Combine("C:\File_Store\", Path.GetFileName(file.FileName)));

            // * OR *
            //Use file.InputStream to access the uploaded file as a stream
            byte[] buffer = new byte[1024];
            int read = file.InputStream.Read(buffer, 0, buffer.Length);
            while (read > 0)
            {
                //do stuff with the buffer
                read = file.InputStream.Read(buffer, 0, buffer.Length);
            }
        }
        return Json(new { Result = "Complete" });
    }
    catch (Exception)
    {
        return Json(new { Result = "Error" });
    }
}

In this case I am returning Json to indicate success, but you can change this to xml (or anything for that matter) if needed.

Tuesday, August 23, 2022
4

Try with regex, to replace the match with nothing

This page suggest :

(/*([^*]|[rn]|(*+([^*/]|[rn])))**+/)|(//.*)

This is also matching the Javadocs, so you would have to tweak it a bit. There are also other variations that you can try.

Have a look at this other SO question. It is suggesting to use an ANT task that is processing the comments and strip them from the source. In this way you can have a button or keyboard shortcut that is calling the ANT task.

As suggestion put a Label in the history before doing big search and replace so later you can compare if want to restore any comments that may have been stripped.

Wednesday, September 14, 2022
 
5

A line-by-line implementation is rather easy and understandable. Assuming that your latitude always start on a new line (which is not what your example give, but it might be a typo), you could do:

latitudes = []
counts = []
blocks = []
current_block = []
for line in test:
    print line
    if line.startswith("latitude"):
        # New block: add the previous one to `blocks` and reset
        blocks.append(current_block)
        current_block = []
        latitudes.append(float(line.split()[-1]))
    elif line.startswith("number_of_data"):
        # Just append the current count to the list
        counts.append(int(line.split()[-1]))
    else:
        # Update the current block
        current_block += [float(f) for f in line.strip().split()]
# Make sure to add the last block...
blocks.append(current_block)
# And to remove the first (empty) one
blocks.pop(0)

You can know check whether all your blocks have the proper size:

all(len(b)==c for (c,b) in zip(counts,blocks))

Alternative solution

If you're concerned about the loops, you may want to consider querying a memory-mapped version of your file. The idea is to find the positions of the lines starting with latitude. Once you find one, find the next and you have a block of text: zap the first two lines (the one starting with latitude and the one starting with number_of_data), combine the remaining ones and process.

import mmap

with open("crap.txt", "r+b") as f:
    # Create the mapper
    mapper = mmap.mmap(f.fileno(), 0)
    # Initialize your output variables
    latitudes = []
    blocks = [] 
    # Find the beginning of the first block
    position = mapper.find("latitude")
    # `position` will be -1 if we can't find it
    while (position >= 0):
        # Move to the beginning of the block
        mapper.seek(position)
        # Read the first line
        lat_line = mapper.readline().strip()
        latitudes.append(lat_line.split()[-1])
        # Read the second one
        zap = mapper.readline()
        # Where are we ?
        start = mapper.tell()
        # Where's the next block ?
        position = mapper.find("latitude")
        # Read the lines and combine them into a large string
        current_block = mapper.read(position-start).replace("n", " ")
        # Transform the string into a list of floats and update the block
        blocks.append(list(float(i) for i in current_block.split() if i))
Monday, September 26, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 

Browse Other Code Languages